Home | History | Annotate | Download | only in dae
      1 /*
      2 * Copyright 2006 Sony Computer Entertainment Inc.
      3 *
      4 * Licensed under the MIT Open Source License, for details please see license.txt or the website
      5 * http://www.opensource.org/licenses/mit-license.php
      6 *
      7 */
      8 
      9 #include <sstream>
     10 #include <dae/daeAtomicType.h>
     11 #include <dae/daeElement.h>
     12 #include <dae/daeURI.h>
     13 #include <dae/daeIDRef.h>
     14 #include <dae/daeMetaElement.h>
     15 #include <dae/daeDatabase.h>
     16 #include <dae/daeErrorHandler.h>
     17 #include <dae/daeUtils.h>
     18 
     19 namespace {
     20 	// Skip leading whitespace
     21 	daeChar* skipWhitespace(daeChar* s) {
     22 		if (s) {
     23 			// !!!GAC NEEDS TO BE CHANGED to use XML standard whitespace parsing
     24 			while(*s == ' ' || *s == '\r' || *s == '\n' || *s == '\t') s++;
     25 		}
     26 
     27 		return s;
     28 	}
     29 
     30 	// Move forward past this token
     31 	daeChar* skipToken(daeChar* s) {
     32 		while(*s != ' ' && *s != '\r' && *s != '\n' && *s != '\t' && *s != 0) s++;
     33 		return s;
     34 	}
     35 
     36 	// Given a string of whitespace-separated tokens, this function returns a null-terminated string
     37 	// containing the next token. If the next token is already null-terminated, no memory is allocated
     38 	// and the function returns the pointer that was passed in. Note that this function assumes that
     39 	// the string passed in starts with the next token and not a whitespace.
     40 	// If returnValue != s, the client should free the returnValue with delete[].
     41 	daeChar* extractToken(daeChar* s) {
     42 		if (!s)
     43 			return 0;
     44 
     45 		daeChar* tmp = skipToken(s);
     46 		if (*tmp != 0) {
     47 			daeChar* scopy = new daeChar[tmp-s+1];
     48 			strncpy(scopy, s, tmp-s);
     49 			scopy[tmp-s] = 0;
     50 			return scopy;
     51 		}
     52 
     53 		return s;
     54 	}
     55 }
     56 
     57 
     58 daeAtomicTypeList::daeAtomicTypeList(DAE& dae) {
     59 	types.append(new daeUIntType(dae));
     60 	types.append(new daeIntType(dae));
     61 	types.append(new daeLongType(dae));
     62 	types.append(new daeShortType(dae));
     63 	types.append(new daeULongType(dae));
     64 	types.append(new daeFloatType(dae));
     65 	types.append(new daeDoubleType(dae));
     66 	types.append(new daeStringRefType(dae));
     67 	types.append(new daeElementRefType(dae));
     68 	types.append(new daeEnumType(dae));
     69 	types.append(new daeRawRefType(dae));
     70 	types.append(new daeResolverType(dae));
     71 	types.append(new daeIDResolverType(dae));
     72 	types.append(new daeBoolType(dae));
     73 	types.append(new daeTokenType(dae));
     74 }
     75 
     76 daeAtomicTypeList::~daeAtomicTypeList() {
     77 	size_t types_count = types.getCount();
     78 	for (size_t i = 0; i < types_count; i++)
     79 		delete types[i];
     80 }
     81 
     82 daeInt daeAtomicTypeList::append(daeAtomicType* t) {
     83 	return (daeInt)types.append(t);
     84 }
     85 
     86 const daeAtomicType* daeAtomicTypeList::getByIndex(daeInt index) {
     87 	return types[index];
     88 }
     89 
     90 daeInt daeAtomicTypeList::getCount() {
     91 	return (daeInt)types.getCount();
     92 }
     93 
     94 daeAtomicType* daeAtomicTypeList::get(daeStringRef typeString) {
     95 	size_t types_count = types.getCount();
     96 	for (size_t i = 0; i < types_count; i++) {
     97 		daeStringRefArray& nameBindings = types[i]->getNameBindings();
     98 		size_t nameBindings_count = nameBindings.getCount();
     99 		for (size_t j = 0; j < nameBindings_count; j++) {
    100 			if (strcmp(typeString, nameBindings[j]) == 0)
    101 				return types[i];
    102 		}
    103 	}
    104 
    105 	return NULL;
    106 }
    107 
    108 daeAtomicType* daeAtomicTypeList::get(daeEnum typeEnum) {
    109 	size_t types_count = types.getCount();
    110 	for (size_t i = 0; i < types_count; i++)
    111 		if (typeEnum == types[i]->getTypeEnum())
    112 			return types[i];
    113 	return NULL;
    114 }
    115 
    116 
    117 daeAtomicType::daeAtomicType(DAE& dae)
    118 {
    119 	_dae = &dae;
    120 	_size = -1;
    121 	_alignment = -1;
    122 	_typeEnum = -1;
    123 	_typeString = "notype";
    124 	_printFormat = "badtype";
    125 	_scanFormat = "";
    126 	_maxStringLength = -1;
    127 }
    128 
    129 daeBool
    130 daeAtomicType::stringToMemory(daeChar *src, daeChar* dstMemory)
    131 {
    132 	sscanf(src, _scanFormat, dstMemory);
    133 	return true;
    134 }
    135 
    136 void daeAtomicType::arrayToString(daeArray& array, std::ostringstream& buffer) {
    137 	if (array.getCount() > 0)
    138 		memoryToString(array.getRaw(0), buffer);
    139 
    140 	size_t array_count = array.getCount();
    141 	for (size_t i = 1; i < array_count; i++) {
    142 		buffer << ' ';
    143 		memoryToString(array.getRaw(i), buffer);
    144 	}
    145 }
    146 
    147 daeBool
    148 daeAtomicType::stringToArray(daeChar* src, daeArray& array) {
    149 	array.clear();
    150 	array.setElementSize(_size);
    151 
    152 	if (src == 0)
    153 		return false;
    154 
    155 	// We're about to insert null terminators into the string so that scanf doesn't take forever
    156 	// doing strlens. Since the memory might not be writable, I need to duplicate the string and
    157 	// write into the duplicate, or else I might get access violations.
    158 	// This sucks... surely we can do better than this.
    159 	daeChar* srcDup = new daeChar[strlen(src)+1];
    160 	strcpy(srcDup, src);
    161 	src = srcDup;
    162 
    163 	while (*src != 0)
    164 	{
    165 		src = skipWhitespace(src);
    166 		if(*src != 0)
    167 		{
    168 			daeChar* token = src;
    169 			src = skipToken(src);
    170 			daeChar temp = *src;
    171 			*src = 0;
    172 			size_t count = array.getCount();
    173 			array.setCount(count+1);
    174 			if (!stringToMemory(token, array.getRaw(count))) {
    175 				delete[] srcDup;
    176 				return false;
    177 			}
    178 
    179 			*src = temp;
    180 		}
    181 	}
    182 
    183 	delete[] srcDup;
    184 	return true;
    185 }
    186 
    187 daeInt daeAtomicType::compareArray(daeArray& value1, daeArray& value2) {
    188 	if (value1.getCount() != value2.getCount())
    189 		return value1.getCount() > value2.getCount() ? 1 : -1;
    190 
    191 	size_t value1_count = value1.getCount();
    192 	for (size_t i = 0; i < value1_count; i++) {
    193 		daeInt result = compare(value1.getRaw(i), value2.getRaw(i));
    194 		if (result != 0)
    195 			return result;
    196 	}
    197 
    198 	return 0;
    199 }
    200 
    201 void daeAtomicType::copyArray(daeArray& src, daeArray& dst) {
    202 	dst.setCount(src.getCount());
    203 	size_t src_count = src.getCount();
    204 	for (size_t i = 0; i < src_count; i++)
    205 		copy(src.getRaw(i), dst.getRaw(i));
    206 }
    207 
    208 daeInt
    209 daeAtomicType::compare(daeChar* value1, daeChar* value2) {
    210 	return memcmp(value1, value2, _size);
    211 }
    212 
    213 daeEnumType::daeEnumType(DAE& dae) : daeAtomicType(dae)
    214 {
    215 	_size = sizeof(daeEnum);
    216 	_alignment = sizeof(daeEnum);
    217 	_typeEnum = EnumType;
    218 	_nameBindings.append("enum");
    219 	_printFormat = "%s";//"%%.%ds";
    220 	_scanFormat = "%s";
    221 	_strings = NULL;
    222 	_values = NULL;
    223 	_typeString = "enum";
    224 }
    225 
    226 daeEnumType::~daeEnumType() {
    227 	if ( _strings ) {
    228 		delete _strings;
    229 		_strings = NULL;
    230 	}
    231 	if ( _values ) {
    232 		delete _values;
    233 		_values = NULL;
    234 	}
    235 }
    236 
    237 daeBoolType::daeBoolType(DAE& dae) : daeAtomicType(dae)
    238 {
    239 	_size = sizeof(daeBool);
    240 	_alignment = sizeof(daeBool);
    241 	_typeEnum = BoolType;
    242 	_printFormat = "%d";
    243 	_scanFormat = "%d";
    244 	_typeString = "bool";
    245 	_maxStringLength = (daeInt)strlen("false")+1;
    246 	_nameBindings.append("bool");
    247 	//_nameBindings.append("xsBool");
    248 	_nameBindings.append("xsBoolean");
    249 }
    250 
    251 daeIntType::daeIntType(DAE& dae) : daeAtomicType(dae)
    252 {
    253 	_size = sizeof(daeInt);
    254 	_alignment = sizeof(daeInt);
    255 	_typeEnum = IntType;
    256 	_maxStringLength = 16;
    257 	_nameBindings.append("int");
    258 	_nameBindings.append("xsInteger");
    259 	_nameBindings.append("xsHexBinary");
    260 	_nameBindings.append("xsIntegerArray");
    261 	_nameBindings.append("xsHexBinaryArray");
    262 	_nameBindings.append("xsByte");
    263 	_nameBindings.append("xsInt");
    264 	_printFormat = "%d";
    265 	_scanFormat = "%d";
    266 	_typeString = "int";
    267 }
    268 daeLongType::daeLongType(DAE& dae) : daeAtomicType(dae)
    269 {
    270 	_size = sizeof(daeLong);
    271 	_alignment = sizeof(daeLong);
    272 	_typeEnum = LongType;
    273 	_maxStringLength = 32;
    274 	_nameBindings.append("xsLong");
    275 	_nameBindings.append("xsLongArray");
    276 #if defined(_MSC_VER) || defined(__MINGW32__)
    277 	_printFormat = "%I64d";
    278 	_scanFormat = "%I64d";
    279 #else
    280 	_printFormat = "%lld";
    281 	_scanFormat = "%lld";
    282 #endif
    283 	_typeString = "long";
    284 }
    285 daeShortType::daeShortType(DAE& dae) : daeAtomicType(dae)
    286 {
    287 	_maxStringLength = 8;
    288 	_size = sizeof(daeShort);
    289 	_alignment = sizeof(daeShort);
    290 	_typeEnum = ShortType;
    291 	_nameBindings.append("short");
    292 	_nameBindings.append("xsShort");
    293 	_printFormat = "%hd";
    294 	_scanFormat = "%hd";
    295 	_typeString = "short";
    296 }
    297 daeUIntType::daeUIntType(DAE& dae) : daeAtomicType(dae)
    298 {
    299 	_maxStringLength = 16;
    300 	_size = sizeof(daeUInt);
    301 	_alignment = sizeof(daeUInt);
    302 	_typeEnum = UIntType;
    303 	_nameBindings.append("uint");
    304 	_nameBindings.append("xsNonNegativeInteger");
    305 	_nameBindings.append("xsUnsignedByte");
    306 	_nameBindings.append("xsUnsignedInt");
    307 	_nameBindings.append("xsPositiveInteger");
    308 	_printFormat = "%u";
    309 	_scanFormat = "%u";
    310 	_typeString = "uint";
    311 }
    312 daeULongType::daeULongType(DAE& dae) : daeAtomicType(dae)
    313 {
    314 	_size = sizeof(daeULong);
    315 	_alignment = sizeof(daeULong);
    316 	_typeEnum = ULongType;
    317 	_maxStringLength = 32;
    318 	_nameBindings.append("ulong");
    319 	_nameBindings.append("xsUnsignedLong");
    320 #if defined(_MSC_VER) || defined(__MINGW32__)
    321 	_printFormat = "%I64u";
    322 	_scanFormat = "%I64u";
    323 #else
    324 	_printFormat = "%llu";
    325 	_scanFormat = "%llu";
    326 #endif
    327 	_typeString = "ulong";
    328 }
    329 daeFloatType::daeFloatType(DAE& dae) : daeAtomicType(dae)
    330 {
    331 	_maxStringLength = 64;
    332 	_size = sizeof(daeFloat);
    333 	_alignment = sizeof(daeFloat);
    334 	_typeEnum = FloatType;
    335 	_nameBindings.append("float");
    336 	_nameBindings.append("xsFloat");
    337 	_printFormat = "%g";
    338 	_scanFormat = "%g";
    339 	_typeString = "float";
    340 }
    341 daeDoubleType::daeDoubleType(DAE& dae) : daeAtomicType(dae)
    342 {
    343 	_size = sizeof(daeDouble);
    344 	_alignment = sizeof(daeDouble);
    345 	_typeEnum = DoubleType;
    346 	_nameBindings.append("double");
    347 	_nameBindings.append("xsDouble");
    348 	_nameBindings.append("xsDecimal");
    349 	_printFormat = "%lg";
    350 	_scanFormat = "%lg";
    351 	_typeString = "double";
    352 	_maxStringLength = 64;
    353 }
    354 
    355 daeStringRefType::daeStringRefType(DAE& dae) : daeAtomicType(dae)
    356 {
    357 	_size = sizeof(daeStringRef);
    358 	_alignment = sizeof(daeStringRef);
    359 	_typeEnum = StringRefType;
    360 	_nameBindings.append("string");
    361 	_nameBindings.append("xsString");
    362 	_nameBindings.append("xsDateTime");
    363 	_printFormat = "%s";
    364 	_scanFormat = "%s";
    365 	_typeString = "string";
    366 }
    367 
    368 daeTokenType::daeTokenType(DAE& dae) : daeStringRefType(dae)
    369 {
    370 	_size = sizeof(daeStringRef);
    371 	_alignment = sizeof(daeStringRef);
    372 	_typeEnum = TokenType;
    373 	_nameBindings.append("token");
    374 	_nameBindings.append("xsID");
    375 	_nameBindings.append("xsNCName");
    376 	_nameBindings.append("xsNMTOKEN");
    377 	_nameBindings.append("xsName");
    378 	_nameBindings.append("xsToken");
    379 	_nameBindings.append("xsNameArray");
    380 	_nameBindings.append("xsTokenArray");
    381 	_nameBindings.append("xsNCNameArray");
    382 	_printFormat = "%s";
    383 	_scanFormat = "%s";
    384 	_typeString = "token";
    385 }
    386 
    387 daeElementRefType::daeElementRefType(DAE& dae) : daeAtomicType(dae)
    388 {
    389 	_size = sizeof(daeElementRef);
    390 	_alignment = sizeof(daeElementRef);
    391 	_typeEnum = ElementRefType;
    392 	_nameBindings.append("element");
    393 	_nameBindings.append("Element");
    394 	_nameBindings.append("TrackedElement");
    395 	_printFormat = "%p";
    396 	_scanFormat = "%p";
    397 	_typeString = "element";
    398 	_maxStringLength = 64;
    399 }
    400 
    401 daeRawRefType::daeRawRefType(DAE& dae) : daeAtomicType(dae)
    402 {
    403 	_size = sizeof(daeRawRef);
    404 	_alignment = sizeof(daeRawRef);
    405 	_typeEnum = RawRefType;
    406 	_nameBindings.append("raw");
    407 	_printFormat = "%p";
    408 	_scanFormat = "%p";
    409 	_typeString = "raw";
    410 	_maxStringLength = 64;
    411 }
    412 
    413 daeResolverType::daeResolverType(DAE& dae) : daeAtomicType(dae)
    414 {
    415 	_size = sizeof(daeURI);
    416 	_alignment = sizeof(daeURI);
    417 	_typeEnum = ResolverType;
    418 	_nameBindings.append("resolver");
    419 	_nameBindings.append("xsAnyURI");
    420 	_printFormat = "%s";
    421 	_scanFormat = "%s";
    422 	_typeString = "resolver";
    423 }
    424 daeIDResolverType::daeIDResolverType(DAE& dae) : daeAtomicType(dae)
    425 {
    426 	_size = sizeof(daeIDRef);
    427 	_alignment = sizeof(daeIDRef);
    428 	_typeEnum = IDResolverType;
    429 	_nameBindings.append("xsIDREF");
    430 	_nameBindings.append("xsIDREFS");
    431 	_printFormat = "%s";
    432 	_scanFormat = "%s";
    433 	_typeString = "idref_resolver";
    434 }
    435 
    436 daeBool daeIntType::memoryToString(daeChar* src, std::ostringstream& dst) {
    437 	dst << *(daeInt*)src;
    438 	return true;
    439 }
    440 
    441 daeBool daeLongType::memoryToString(daeChar* src, std::ostringstream& dst) {
    442 	dst << *(daeLong*)src;
    443 	return true;
    444 }
    445 
    446 daeBool daeShortType::memoryToString(daeChar* src, std::ostringstream& dst) {
    447 	dst << *(daeShort*)src;
    448 	return true;
    449 }
    450 
    451 daeBool daeUIntType::memoryToString(daeChar* src, std::ostringstream& dst) {
    452 	dst << *(daeUInt*)src;
    453 	return true;
    454 }
    455 
    456 daeBool daeULongType::memoryToString(daeChar* src, std::ostringstream& dst) {
    457 #ifdef _MSC_VER
    458 	// Microsoft's stringstream implementation has weird performance issues
    459 	static char buffer[64];
    460 	_snprintf(buffer, 64, _printFormat, *((daeULong*)src));
    461 	dst << buffer;
    462 #else
    463 	dst << *(daeULong*)src;
    464 #endif
    465 	return true;
    466 }
    467 
    468 daeBool daeFloatType::memoryToString(daeChar* src, std::ostringstream& dst) {
    469 	if ( *(daeFloat*)src != *(daeFloat*)src ) // NAN
    470 		dst << "NaN";
    471 	else if ( *(daeUInt*)src == 0x7f800000 ) // +INF
    472 		dst << "INF";
    473 	else if ( *(daeUInt*)src == 0xff800000 ) // -INF
    474 		dst << "-INF";
    475 	else
    476 		dst << *(daeFloat*)src;
    477 	return true;
    478 }
    479 
    480 daeBool
    481 daeFloatType::stringToMemory(daeChar *src, daeChar* dstMemory)
    482 {
    483 	src = skipWhitespace(src);
    484 
    485 	if ( strncmp(src, "NaN", 3) == 0 ) {
    486 		daeErrorHandler::get()->handleWarning("NaN encountered while setting an attribute or value\n");
    487 		*(daeInt*)(dstMemory) = 0x7f800002;
    488 	}
    489 	else if ( strncmp(src, "INF", 3) == 0 ) {
    490 		daeErrorHandler::get()->handleWarning( "INF encountered while setting an attribute or value\n" );
    491 		*(daeInt*)(dstMemory) = 0x7f800000;
    492 	}
    493 	else if ( strncmp(src, "-INF", 4) == 0 ) {
    494 		daeErrorHandler::get()->handleWarning( "-INF encountered while setting an attribute or value\n" );
    495 		*(daeInt*)(dstMemory) = 0xff800000;
    496 	}
    497 	else
    498 	{
    499 		sscanf(src, _scanFormat, dstMemory);
    500 	}
    501 	return true;
    502 }
    503 
    504 daeBool daeDoubleType::memoryToString(daeChar* src, std::ostringstream& dst) {
    505 	if ( *(daeDouble*)src != *(daeDouble*)src ) // NAN
    506 		dst << "NaN";
    507 	else if ( *(daeULong*)src == 0x7ff0000000000000LL ) // +INF
    508 		dst << "INF";
    509 	else if ( *(daeULong*)src == 0xfff0000000000000LL ) // -INF
    510 		dst << "-INF";
    511 	else {
    512 #ifdef _MSC_VER
    513 		// Microsoft's stringstream implementation has weird performance issues
    514 		static char buffer[64];
    515 		_snprintf(buffer, 64, _printFormat, *((daeDouble*)src));
    516 		dst << buffer;
    517 #else
    518 		dst << *(daeDouble*)src;
    519 #endif
    520 	}
    521 	return true;
    522 }
    523 
    524 daeBool
    525 daeDoubleType::stringToMemory(daeChar *src, daeChar* dstMemory)
    526 {
    527 	src = skipWhitespace(src);
    528 
    529 	if ( strncmp(src, "NaN", 3) == 0 ) {
    530 		daeErrorHandler::get()->handleWarning( "NaN encountered while setting an attribute or value\n" );
    531 		*(daeLong*)(dstMemory) = 0x7ff0000000000002LL;
    532 	}
    533 	else if ( strncmp(src, "INF", 3) == 0 ) {
    534 		daeErrorHandler::get()->handleWarning( "INF encountered while setting an attribute or value\n" );
    535 		*(daeLong*)(dstMemory) = 0x7ff0000000000000LL;
    536 	}
    537 	else if ( strncmp(src, "-INF", 4) == 0 ) {
    538 		daeErrorHandler::get()->handleWarning( "-INF encountered while setting an attribute or value\n" );
    539 		*(daeLong*)(dstMemory) = 0xfff0000000000000LL;
    540 	}
    541 	else
    542 	{
    543 		sscanf(src, _scanFormat, dstMemory);
    544 	}
    545 	return true;
    546 }
    547 
    548 daeBool daeRawRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
    549 	dst << (void *)(*((daeRawRef*)src));
    550 	return true;
    551 }
    552 
    553 daeBool daeStringRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
    554 	daeString s = *((daeStringRef *)src);
    555 	if (s)
    556 		dst << s;
    557 	return true;
    558 }
    559 
    560 daeBool daeResolverType::memoryToString(daeChar* src, std::ostringstream& dst) {
    561 	// Get the URI we are trying to write
    562 	daeURI *thisURI = ((daeURI *)src);
    563 	// Encode spaces with %20
    564 	dst << cdom::replace(thisURI->originalStr(), " ", "%20");
    565 	return true;
    566 }
    567 
    568 daeBool daeIDResolverType::memoryToString(daeChar* src, std::ostringstream& dst) {
    569 	dst << ((daeIDRef *)src)->getID();
    570 	return true;
    571 }
    572 
    573 daeBool
    574 daeResolverType::stringToMemory(daeChar* src, daeChar* dstMemory)
    575 {
    576 	((daeURI*)dstMemory)->set(cdom::replace(src, " ", "%20"));
    577 	return true;
    578 }
    579 
    580 daeBool
    581 daeIDResolverType::stringToMemory(daeChar* src, daeChar* dstMemory)
    582 {
    583 	src = skipWhitespace(src);
    584 	daeChar* id = extractToken(src);
    585 	((daeIDRef*)dstMemory)->setID(id);
    586 	if (id != src)
    587 		delete[] id;
    588 	return true;
    589 }
    590 
    591 daeBool
    592 daeStringRefType::stringToMemory(daeChar* srcChars, daeChar* dstMemory)
    593 {
    594 	*((daeStringRef*)dstMemory) = srcChars;
    595 	return true;
    596 }
    597 
    598 daeBool
    599 daeTokenType::stringToMemory(daeChar* src, daeChar* dst)
    600 {
    601 	src = skipWhitespace(src);
    602 	daeChar* srcTmp = extractToken(src);
    603 	*((daeStringRef*)dst) = srcTmp;
    604 	if (srcTmp != src)
    605 		delete[] srcTmp;
    606 	return true;
    607 }
    608 
    609 daeBool
    610 daeEnumType::stringToMemory(daeChar* src, daeChar* dst )
    611 {
    612 	src = skipWhitespace(src);
    613 	daeChar* srcTmp = extractToken(src);
    614 
    615 	size_t index(0);
    616 	bool result = _strings->find(srcTmp, index) != DAE_ERR_QUERY_NO_MATCH;
    617 	if (result) {
    618 		daeEnum val = _values->get( index );
    619 		*((daeEnum*)dst) = val;
    620 	}
    621 
    622 	if (srcTmp != src)
    623 		delete[] srcTmp;
    624 
    625 	return result;
    626 }
    627 
    628 daeBool daeEnumType::memoryToString(daeChar* src, std::ostringstream& dst) {
    629 	daeStringRef s = "unknown";
    630 	if (_strings != NULL) {
    631 		size_t index;
    632 		if (_values->find(*((daeEnum*)src), index) == DAE_OK)
    633 			s = _strings->get(index);
    634 	}
    635 	dst << (const char*)s;
    636 	return true;
    637 }
    638 
    639 daeBool
    640 daeBoolType::stringToMemory(daeChar* srcChars, daeChar* dstMemory)
    641 {
    642 	if (strncmp(srcChars,"true",4)==0 || strncmp(srcChars,"1",1)==0)
    643 		*((daeBool*)dstMemory) = true;
    644 	else
    645 		*((daeBool*)dstMemory) = false;
    646 	return true;
    647 }
    648 
    649 daeBool daeBoolType::memoryToString(daeChar* src, std::ostringstream& dst) {
    650 	if (*((daeBool*)src))
    651 		dst << "true";
    652 	else
    653 		dst << "false";
    654 	return true;
    655 }
    656 //!!!ACL added for 1.4 complex types and groups
    657 
    658 // Unimplemented
    659 daeBool daeElementRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
    660 	(void)src;
    661 	(void)dst;
    662 	return false;
    663 }
    664 
    665 daeMemoryRef daeBoolType::create() {
    666 	return (daeMemoryRef)new daeBool;
    667 }
    668 
    669 daeMemoryRef daeIntType::create() {
    670 	return (daeMemoryRef)new daeInt;
    671 }
    672 
    673 daeMemoryRef daeLongType::create() {
    674 	return (daeMemoryRef)new daeLong;
    675 }
    676 
    677 daeMemoryRef daeUIntType::create() {
    678 	return (daeMemoryRef)new daeUInt;
    679 }
    680 
    681 daeMemoryRef daeULongType::create() {
    682 	return (daeMemoryRef)new daeULong;
    683 }
    684 
    685 daeMemoryRef daeShortType::create() {
    686 	return (daeMemoryRef)new daeShort;
    687 }
    688 
    689 daeMemoryRef daeFloatType::create() {
    690 	return (daeMemoryRef)new daeFloat;
    691 }
    692 
    693 daeMemoryRef daeDoubleType::create() {
    694 	return (daeMemoryRef)new daeDouble;
    695 }
    696 
    697 daeMemoryRef daeStringRefType::create() {
    698 	return (daeMemoryRef)new daeStringRef;
    699 }
    700 
    701 daeMemoryRef daeTokenType::create() {
    702 	return (daeMemoryRef)new daeStringRef;
    703 }
    704 
    705 daeMemoryRef daeElementRefType::create() {
    706 	return (daeMemoryRef)new daeElementRef;
    707 }
    708 
    709 daeMemoryRef daeEnumType::create() {
    710 	return (daeMemoryRef)new daeEnum;
    711 }
    712 
    713 daeMemoryRef daeRawRefType::create() {
    714 	return (daeMemoryRef)new daeRawRef;
    715 }
    716 
    717 daeMemoryRef daeResolverType::create() {
    718 	return (daeMemoryRef)new daeURI(*_dae);
    719 }
    720 
    721 daeMemoryRef daeIDResolverType::create() {
    722 	return (daeMemoryRef)new daeIDRef;
    723 }
    724 
    725 
    726 void daeBoolType::destroy(daeMemoryRef obj) {
    727 	delete (daeBool*)obj;
    728 }
    729 
    730 void daeIntType::destroy(daeMemoryRef obj) {
    731 	delete (daeInt*)obj;
    732 }
    733 
    734 void daeLongType::destroy(daeMemoryRef obj) {
    735 	delete (daeLong*)obj;
    736 }
    737 
    738 void daeUIntType::destroy(daeMemoryRef obj) {
    739 	delete (daeUInt*)obj;
    740 }
    741 
    742 void daeULongType::destroy(daeMemoryRef obj) {
    743 	delete (daeULong*)obj;
    744 }
    745 
    746 void daeShortType::destroy(daeMemoryRef obj) {
    747 	delete (daeShort*)obj;
    748 }
    749 
    750 void daeFloatType::destroy(daeMemoryRef obj) {
    751 	delete (daeFloat*)obj;
    752 }
    753 
    754 void daeDoubleType::destroy(daeMemoryRef obj) {
    755 	delete (daeDouble*)obj;
    756 }
    757 
    758 void daeStringRefType::destroy(daeMemoryRef obj) {
    759 	delete (daeStringRef*)obj;
    760 }
    761 
    762 void daeTokenType::destroy(daeMemoryRef obj) {
    763 	delete (daeStringRef*)obj;
    764 }
    765 
    766 void daeElementRefType::destroy(daeMemoryRef obj) {
    767 	delete (daeElementRef*)obj;
    768 }
    769 
    770 void daeEnumType::destroy(daeMemoryRef obj) {
    771 	delete (daeEnum*)obj;
    772 }
    773 
    774 void daeRawRefType::destroy(daeMemoryRef obj) {
    775 	delete (daeRawRef*)obj;
    776 }
    777 
    778 void daeResolverType::destroy(daeMemoryRef obj) {
    779 	delete (daeURI*)obj;
    780 }
    781 
    782 void daeIDResolverType::destroy(daeMemoryRef obj) {
    783 	delete (daeIDRef*)obj;
    784 }
    785 
    786 
    787 daeInt daeStringRefType::compare(daeChar* value1, daeChar* value2) {
    788 	daeString s1 = *((daeStringRef *)value1);
    789 	daeString s2 = *((daeStringRef *)value2);
    790 	// For string types, the empty string and null are considered equivalent
    791 	if (!s1)
    792 		s1 = "";
    793 	if (!s2)
    794 		s2 = "";
    795 	return strcmp(s1, s2);
    796 }
    797 
    798 daeInt daeResolverType::compare(daeChar* value1, daeChar* value2) {
    799 	return strcmp(((daeURI*)value1)->str().c_str(), ((daeURI*)value2)->str().c_str());
    800 }
    801 
    802 daeInt daeIDResolverType::compare(daeChar* value1, daeChar* value2) {
    803 	return (daeIDRef&)*value1 == (daeIDRef&)*value2;
    804 }
    805 
    806 
    807 daeArray* daeBoolType::createArray() {
    808 	return new daeTArray<daeBool>;
    809 }
    810 
    811 daeArray* daeIntType::createArray() {
    812 	return new daeTArray<daeInt>;
    813 }
    814 
    815 daeArray* daeLongType::createArray() {
    816 	return new daeTArray<daeLong>;
    817 }
    818 
    819 daeArray* daeUIntType::createArray() {
    820 	return new daeTArray<daeUInt>;
    821 }
    822 
    823 daeArray* daeULongType::createArray() {
    824 	return new daeTArray<daeULong>;
    825 }
    826 
    827 daeArray* daeShortType::createArray() {
    828 	return new daeTArray<daeShort>;
    829 }
    830 
    831 daeArray* daeFloatType::createArray() {
    832 	return new daeTArray<daeFloat>;
    833 }
    834 
    835 daeArray* daeDoubleType::createArray() {
    836 	return new daeTArray<daeDouble>;
    837 }
    838 
    839 daeArray* daeStringRefType::createArray() {
    840 	return new daeTArray<daeStringRef>;
    841 }
    842 
    843 daeArray* daeTokenType::createArray() {
    844 	return new daeTArray<daeStringRef>;
    845 }
    846 
    847 daeArray* daeElementRefType::createArray() {
    848 	return new daeTArray<daeElementRef>;
    849 }
    850 
    851 daeArray* daeEnumType::createArray() {
    852 	return new daeTArray<daeEnum>;
    853 }
    854 
    855 daeArray* daeRawRefType::createArray() {
    856 	return new daeTArray<daeRawRef>;
    857 }
    858 
    859 daeArray* daeResolverType::createArray() {
    860 	// !!!steveT
    861 	// The daeURI object no longer has a constructor that takes no arguments, so
    862 	// it's not compatible with daeTArray. Therefore this method currently can't be used,
    863 	// and asserts if you try to use it. The DOM doesn't ever call this code now,
    864 	// so the situation is sort of alright, but we might need to fix this in the future.
    865 	assert(false);
    866 	return NULL;
    867 }
    868 
    869 daeArray* daeIDResolverType::createArray() {
    870 	return new daeTArray<daeIDRef>;
    871 }
    872 
    873 
    874 void daeBoolType::copy(daeChar* src, daeChar* dst) {
    875 	(daeBool&)*dst = (daeBool&)*src;
    876 }
    877 
    878 void daeIntType::copy(daeChar* src, daeChar* dst) {
    879 	(daeInt&)*dst = (daeInt&)*src;
    880 }
    881 
    882 void daeLongType::copy(daeChar* src, daeChar* dst) {
    883 	(daeLong&)*dst = (daeLong&)*src;
    884 }
    885 
    886 void daeUIntType::copy(daeChar* src, daeChar* dst) {
    887 	(daeUInt&)*dst = (daeUInt&)*src;
    888 }
    889 
    890 void daeULongType::copy(daeChar* src, daeChar* dst) {
    891 	(daeULong&)*dst = (daeULong&)*src;
    892 }
    893 
    894 void daeShortType::copy(daeChar* src, daeChar* dst) {
    895 	(daeShort&)*dst = (daeShort&)*src;
    896 }
    897 
    898 void daeFloatType::copy(daeChar* src, daeChar* dst) {
    899 	(daeFloat&)*dst = (daeFloat&)*src;
    900 }
    901 
    902 void daeDoubleType::copy(daeChar* src, daeChar* dst) {
    903 	(daeDouble&)*dst = (daeDouble&)*src;
    904 }
    905 
    906 void daeStringRefType::copy(daeChar* src, daeChar* dst) {
    907 	(daeStringRef&)*dst = (daeStringRef&)*src;
    908 }
    909 
    910 void daeTokenType::copy(daeChar* src, daeChar* dst) {
    911 	(daeStringRef&)*dst = (daeStringRef&)*src;
    912 }
    913 
    914 void daeElementRefType::copy(daeChar* src, daeChar* dst) {
    915 	(daeElementRef&)*dst = (daeElementRef&)*src;
    916 }
    917 
    918 void daeEnumType::copy(daeChar* src, daeChar* dst) {
    919 	(daeEnum&)*dst = (daeEnum&)*src;
    920 }
    921 
    922 void daeRawRefType::copy(daeChar* src, daeChar* dst) {
    923 	(daeRawRef&)*dst = (daeRawRef&)*src;
    924 }
    925 
    926 void daeResolverType::copy(daeChar* src, daeChar* dst) {
    927 	(daeURI&)*dst = (daeURI&)*src;
    928 }
    929 
    930 void daeIDResolverType::copy(daeChar* src, daeChar* dst) {
    931 	(daeIDRef&)*dst = (daeIDRef&)*src;
    932 }
    933 
    934 void daeResolverType::setDocument(daeChar* value, daeDocument* doc) {
    935 	daeURI* uri = (daeURI*)value;
    936 	uri->setContainer(uri->getContainer());
    937 }
    938 
    939 void daeResolverType::setDocument(daeArray& array, daeDocument* doc) {
    940 	// !!!steveT
    941 	// The daeURI object no longer has a constructor that takes no arguments, so
    942 	// it's not compatible with daeTArray. Therefore this method currently can't be used,
    943 	// and asserts if you try to use it. The DOM doesn't ever call this code now,
    944 	// so the situation is sort of alright, but we might need to fix this in the future.
    945 	assert(false);
    946 }
    947