//-------------------------------------- StringTableEntry _StringTable::lookupn(const char* val, S32 len, const bool caseSens) { Node **walk, *temp; U32 key = hashStringn(val, len); walk = &buckets[key % numBuckets]; while((temp = *walk) != NULL) { if(caseSens && !dStrncmp(temp->val, val, len) && temp->val[len] == 0) return temp->val; else if(!caseSens && !dStrnicmp(temp->val, val, len) && temp->val[len] == 0) return temp->val; walk = &(temp->next); } return NULL; }
bool SFXWavStream::_readHeader() { // We read the wav chunks to gather than header info // and find the start and end position of the data chunk. mDataStart = -1; WAVFileHdr fileHdr; mStream->read( 4, &fileHdr.id[0] ); mStream->read( &fileHdr.size ); mStream->read( 4, &fileHdr.type[0] ); fileHdr.size=((fileHdr.size+1)&~1)-4; WAVChunkHdr chunkHdr; mStream->read( 4, &chunkHdr.id[0] ); mStream->read( &chunkHdr.size ); // Unread chunk data rounded up to nearest WORD. S32 chunkRemaining = chunkHdr.size + ( chunkHdr.size & 1 ); WAVFmtHdr fmtHdr; WAVFmtExHdr fmtExHdr; WAVSmplHdr smplHdr; dMemset(&fmtHdr, 0, sizeof(fmtHdr)); while ((fileHdr.size!=0) && (mStream->getStatus() != Stream::EOS)) { // WAV format header chunk. if ( !dStrncmp( (const char*)chunkHdr.id, "fmt ", 4 ) ) { mStream->read(&fmtHdr.format); mStream->read(&fmtHdr.channels); mStream->read(&fmtHdr.samplesPerSec); mStream->read(&fmtHdr.bytesPerSec); mStream->read(&fmtHdr.blockAlign); mStream->read(&fmtHdr.bitsPerSample); if ( fmtHdr.format == 0x0001 ) { mFormat.set( fmtHdr.channels, fmtHdr.bitsPerSample * fmtHdr.channels, fmtHdr.samplesPerSec ); chunkRemaining -= sizeof( WAVFmtHdr ); } else { mStream->read(sizeof(WAVFmtExHdr), &fmtExHdr); chunkRemaining -= sizeof(WAVFmtExHdr); } } // WAV data chunk else if (!dStrncmp((const char*)chunkHdr.id,"data",4)) { // TODO: Handle these other formats in a more graceful manner! if (fmtHdr.format==0x0001) { mDataStart = mStream->getPosition(); mStream->setPosition( mDataStart + chunkHdr.size ); chunkRemaining -= chunkHdr.size; mSamples = chunkHdr.size / mFormat.getBytesPerSample(); } else if (fmtHdr.format==0x0011) { //IMA ADPCM } else if (fmtHdr.format==0x0055) { //MP3 WAVE } } // WAV sample header else if (!dStrncmp((const char*)chunkHdr.id,"smpl",4)) { // this struct read is NOT endian safe but it is ok because // we are only testing the loops field against ZERO mStream->read(sizeof(WAVSmplHdr), &smplHdr); // This has never been hooked up and its usefulness is // dubious. Do we really want the audio file overriding // the SFXDescription setting? //mLooping = ( smplHdr.loops ? true : false ); chunkRemaining -= sizeof(WAVSmplHdr); } // either we have unread chunk data or we found an unknown chunk type // loop and read up to 1K bytes at a time until we have // read to the end of this chunk AssertFatal(chunkRemaining >= 0, "AudioBuffer::readWAV: remaining chunk data should never be less than zero."); if ( chunkRemaining > 0 ) { U32 pos = mStream->getPosition(); mStream->setPosition( pos + chunkRemaining ); chunkRemaining = 0; } fileHdr.size-=(((chunkHdr.size+1)&~1)+8); // read next chunk header... mStream->read(4, &chunkHdr.id[0]); mStream->read(&chunkHdr.size); // unread chunk data rounded up to nearest WORD chunkRemaining = chunkHdr.size + (chunkHdr.size&1); } return ( mDataStart != -1 ); }
static bool recurseDumpDirectories(const char *basePath, const char *subPath, Vector<StringTableEntry> &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath) { TempAlloc< char > search( 1024 ); //----------------------------------------------------------------------------- // Compose our search string - Format : ([path]/[subpath]/*) //----------------------------------------------------------------------------- char trail = basePath[ dStrlen(basePath) - 1 ]; char subTrail = subPath ? subPath[ dStrlen(subPath) - 1 ] : '\0'; if( trail == '/' ) { // we have a sub path and it's not an empty string if( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) { if( subTrail == '/' ) dSprintf(search, search.size, "%s%s*", basePath,subPath ); else dSprintf(search, search.size, "%s%s/*", basePath,subPath ); } else dSprintf( search, search.size, "%s*", basePath ); } else { if( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) if( subTrail == '/' ) dSprintf(search, search.size, "%s%s*", basePath,subPath ); else dSprintf(search, search.size, "%s%s/*", basePath,subPath ); else dSprintf(search, search.size, "%s/*", basePath ); } #ifdef UNICODE TempAlloc< WCHAR > searchStr( dStrlen( search ) + 1 ); convertUTF8toUTF16( search, searchStr, searchStr.size ); #else char* searchStr = search; #endif backslash( searchStr ); //----------------------------------------------------------------------------- // See if we get any hits //----------------------------------------------------------------------------- WIN32_FIND_DATA findData; HANDLE handle = FindFirstFile(searchStr, &findData); if (handle == INVALID_HANDLE_VALUE) return false; //----------------------------------------------------------------------------- // add path to our return list ( provided it is valid ) //----------------------------------------------------------------------------- if( !Platform::isExcludedDirectory( subPath ) ) { if( noBasePath ) { // We have a path and it's not an empty string or an excluded directory if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) ) directoryVector.push_back( StringTable->insert( subPath ) ); } else { if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) ) { char szPath [ 1024 ]; dMemset( szPath, 0, 1024 ); if( trail != '/' ) dSprintf( szPath, 1024, "%s%s", basePath, subPath ); else dSprintf( szPath, 1024, "%s%s", basePath, &subPath[1] ); directoryVector.push_back( StringTable->insert( szPath ) ); } else directoryVector.push_back( StringTable->insert( basePath ) ); } } //----------------------------------------------------------------------------- // Iterate through and grab valid directories //----------------------------------------------------------------------------- #ifdef UNICODE TempAlloc< char > fileName( 1024 ); #endif do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // skip . and .. directories if (dStrcmp(findData.cFileName, TEXT( "." )) == 0 || dStrcmp(findData.cFileName, TEXT( ".." )) == 0) continue; #ifdef UNICODE convertUTF16toUTF8( findData.cFileName, fileName, fileName.size ); #else char* fileName = findData.cFileName; #endif // skip excluded directories if( Platform::isExcludedDirectory( fileName ) ) continue; if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) )) { if( subTrail == '/' ) dSprintf(search, search.size, "%s%s", subPath, fileName); else dSprintf(search, search.size, "%s/%s", subPath, fileName); char* child = search; if( currentDepth < recurseDepth || recurseDepth == -1 ) recurseDumpDirectories(basePath, child, directoryVector, currentDepth+1, recurseDepth, noBasePath ); } else { char* child; if( trail == '/' ) child = fileName; else { dSprintf(search, search.size, "/%s", fileName); child = search; } if( currentDepth < recurseDepth || recurseDepth == -1 ) recurseDumpDirectories(basePath, child, directoryVector, currentDepth+1, recurseDepth, noBasePath ); } } } while(FindNextFile(handle, &findData)); FindClose(handle); return true; }
static bool recurseDumpDirectories(const char *basePath, const char *subPath, Vector<StringTableEntry> &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath) { char Path[1024]; DIR *dip; struct dirent *d; if (subPath && (dStrncmp(subPath, "", 1) != 0)) { if ((basePath[dStrlen(basePath) - 1]) == '/') dSprintf(Path, 1024, "%s%s", basePath, subPath); else dSprintf(Path, 1024, "%s/%s", basePath, subPath); } else dSprintf(Path, 1024, "%s", basePath); dip = opendir(Path); if (dip == NULL) return false; ////////////////////////////////////////////////////////////////////////// // add path to our return list ( provided it is valid ) ////////////////////////////////////////////////////////////////////////// if (!Platform::isExcludedDirectory(subPath)) { if (noBasePath) { // We have a path and it's not an empty string or an excluded directory if ( (subPath && (dStrncmp (subPath, "", 1) != 0)) ) directoryVector.push_back(StringTable->insert(subPath)); } else { if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) { char szPath[1024]; dMemset(szPath, 0, 1024); if ( (basePath[dStrlen(basePath) - 1]) != '/') dSprintf(szPath, 1024, "%s%s", basePath, subPath); else dSprintf(szPath, 1024, "%s%s", basePath, &subPath[1]); directoryVector.push_back(StringTable->insert(szPath)); } else directoryVector.push_back(StringTable->insert(basePath)); } } ////////////////////////////////////////////////////////////////////////// // Iterate through and grab valid directories ////////////////////////////////////////////////////////////////////////// while (d = readdir(dip)) { bool isDir; isDir = false; if (d->d_type == DT_UNKNOWN) { char child [1024]; if ((Path[dStrlen(Path) - 1] == '/')) dSprintf(child, 1024, "%s%s", Path, d->d_name); else dSprintf(child, 1024, "%s/%s", Path, d->d_name); isDir = Platform::isDirectory (child); } else if (d->d_type & DT_DIR) isDir = true; if ( isDir ) { if (dStrcmp(d->d_name, ".") == 0 || dStrcmp(d->d_name, "..") == 0) continue; if (Platform::isExcludedDirectory(d->d_name)) continue; if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) { char child[1024]; if ((subPath[dStrlen(subPath) - 1] == '/')) dSprintf(child, 1024, "%s%s", subPath, d->d_name); else dSprintf(child, 1024, "%s/%s", subPath, d->d_name); if (currentDepth < recurseDepth || recurseDepth == -1 ) recurseDumpDirectories(basePath, child, directoryVector, currentDepth + 1, recurseDepth, noBasePath); } else { char child[1024]; if ( (basePath[dStrlen(basePath) - 1]) == '/') dStrcpy (child, d->d_name); else dSprintf(child, 1024, "/%s", d->d_name); if (currentDepth < recurseDepth || recurseDepth == -1) recurseDumpDirectories(basePath, child, directoryVector, currentDepth + 1, recurseDepth, noBasePath); } } } closedir(dip); return true; }
/// Helper to parse argument names out of a prototype string. static Vector< String > parseFunctionArgumentNames( const EngineFunctionInfo* function ) { Vector< String > argNames; const char* prototype = function->getPrototypeString(); if( !prototype ) return argNames; const U32 prototypeLength = dStrlen( prototype ); const char* prototypeEnd = &prototype[ prototypeLength ]; const char* ptr = prototypeEnd - 1; // Search for right parenthesis. while( ptr >= prototype && *ptr != ')' ) ptr --; if( ptr < prototype ) return argNames; ptr --; while( ptr >= prototype && *ptr != '(' ) { // Skip back over spaces. while( ptr >= prototype && dIsspace( *ptr ) ) ptr --; if( ptr < prototype ) return argNames; // Parse out name. const char* end = ptr + 1; while( ptr > prototype && dIsalnum( *ptr ) ) ptr --; const char* start = ptr + 1; // Skip back over spaces. while( ptr >= prototype && dIsspace( *ptr ) ) ptr --; // If we're sure we don't have just a type name without an // argument name, copy out the argument name name. if( ptr >= prototype && *ptr != ',' && *ptr != '(' && end > start ) argNames.push_front( String( start, end - start ) ); else argNames.push_front( "" ); // Skip back to comma or opening parenthesis. U32 parenNestingCount = 0; while( ptr >= prototype ) { if( *ptr == ')' ) parenNestingCount ++; else if( *ptr == '(' ) parenNestingCount --; else if( *ptr == ',' && parenNestingCount == 0 ) { ptr --; break; } else if( *ptr == '(' && parenNestingCount == 0 ) break; ptr --; } } // Add 'this' parameter if this is a method. if( dStrncmp( prototype, "virtual ", sizeof( "virtual " ) - 1 ) == 0 ) argNames.push_front( "this" ); return argNames; }