home *** CD-ROM | disk | FTP | other *** search
/ Game Audio Programming / GameAudioProgramming.iso / Game_Audio / audio_sdk / src / AudioScript / TokenFile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-05-31  |  16.2 KB  |  698 lines

  1. /***********************************************************\
  2. Copyright (C) James Boer, 2002. 
  3. All rights reserved worldwide.
  4.  
  5. This software is provided "as is" without express or implied
  6. warranties. You may freely copy and compile this source into
  7. applications you distribute provided that the copyright text
  8. below is included in the resulting source code, for example:
  9. "Portions Copyright (C) James Boer, 2002"
  10. \***********************************************************/
  11.  
  12. #include "Audio.h"
  13. #include "TokenFile.h"
  14.  
  15. using namespace std;
  16. using namespace Audio;
  17.  
  18. const char* PCS_HEADER = "PCSFILE";
  19. const unsigned short PCS_MAJOR_VERSION = 1;
  20. const unsigned short PCS_MINOR_VERSION = 0;
  21.  
  22.  
  23. //------------------------------------------------------------------------//
  24. void TokenFile::Clear()
  25. {
  26.     m_pTokenList = NULL;
  27.     m_bCaseSensitive = false;
  28.     m_bWordKeywordIndex = false;
  29.     m_bWordOperatorIndex = false;
  30.     m_bWordVariableIndex = false;
  31.     m_vecKeyword.clear();
  32.     m_vecOperator.clear();
  33.     m_vecVariable.clear();
  34. }
  35.  
  36. //------------------------------------------------------------------------//
  37. void TokenFile::Term()
  38. {
  39.     Clear();
  40. }
  41.  
  42.  
  43.  
  44. //------------------------------------------------------------------------//
  45. bool TokenFile::Write(ostream &Output, TokenList* pTokenList, DWORD dwFlags)
  46. {
  47.     Clear();
  48.     
  49.     if(dwFlags & TF_CASE_SENSITIVE)
  50.         m_bCaseSensitive = true;
  51.     else
  52.         m_bCaseSensitive = false;
  53.  
  54.     // clear the queue
  55.     while(!m_queBuffer.empty())
  56.         m_queBuffer.pop();
  57.  
  58.     m_pTokenList = pTokenList;
  59.     WriteHeader();
  60.     GenerateTables();
  61.     WriteTables();
  62.     WriteTokens();
  63.  
  64.     while(!m_queBuffer.empty())
  65.     {
  66.         Output.put(m_queBuffer.front());
  67.         m_queBuffer.pop();
  68.     }
  69.  
  70.     Output.flush();
  71.     return true;
  72. }
  73.  
  74. //------------------------------------------------------------------------//
  75. bool TokenFile::Write(string sFilename, TokenList* pTokenList, DWORD dwFlags)
  76. {
  77.     ofstream File;
  78.  
  79.     if(pTokenList == NULL)
  80.         return Error::Handle("Function requires a valid token list");
  81.  
  82.     File.open(sFilename.c_str(), ios::out | ios::binary | ios::trunc);
  83.  
  84.     if(!File.good())
  85.         return Error::Handle("ERROR: file %s can't be opened for writing.\n",(const char*)sFilename.c_str());
  86.  
  87.     return Write(File, pTokenList);
  88. }
  89.  
  90.  
  91.  
  92. //------------------------------------------------------------------------//
  93. void TokenFile::WriteHeader()
  94. {
  95.     for(int i = 0; i < 7; i++)
  96.         m_queBuffer.push(PCS_HEADER[i]);
  97.  
  98.     WriteWord(PCS_MAJOR_VERSION);
  99.     WriteWord(PCS_MINOR_VERSION);
  100. }
  101.  
  102.  
  103. //------------------------------------------------------------------------//
  104. // Iterate through the list and pre-generate string-based tokens
  105. void TokenFile::GenerateTables()
  106. {
  107.     for(TokenListItor itor = m_pTokenList->begin(); itor != m_pTokenList->end(); ++itor)
  108.     {
  109.         if(itor->IsKeyword())
  110.         {
  111.             bool bFound = false;
  112.             for(int i = 0; i < m_vecKeyword.size(); i++)
  113.             {
  114.                 if(m_bCaseSensitive)
  115.                 {
  116.                     if(strcmp(m_vecKeyword[i].c_str(), itor->GetKeyword()) == 0)
  117.                     {
  118.                         bFound = true;
  119.                         break;
  120.                     }
  121.                 }
  122.                 else
  123.                 {
  124.                     if(stricmp(m_vecKeyword[i].c_str(), itor->GetKeyword()) == 0)
  125.                     {
  126.                         bFound = true;
  127.                         break;
  128.                     }
  129.                 }
  130.             }
  131.             if(!bFound)
  132.                 m_vecKeyword.push_back(itor->GetKeyword());
  133.         }
  134.         else if(itor->IsOperator())
  135.         {
  136.             bool bFound = false;
  137.             for(int i = 0; i < m_vecOperator.size(); i++)
  138.             {
  139.                 if(m_bCaseSensitive)
  140.                 {
  141.                     if(strcmp(m_vecOperator[i].c_str(), itor->GetOperator()) == 0)
  142.                     {
  143.                         bFound = true;
  144.                         break;
  145.                     }
  146.                 }
  147.                 else
  148.                 {
  149.                     if(stricmp(m_vecOperator[i].c_str(), itor->GetOperator()) == 0)
  150.                     {
  151.                         bFound = true;
  152.                         break;
  153.                     }
  154.                 }
  155.             }
  156.             if(!bFound)
  157.                 m_vecOperator.push_back(itor->GetOperator());
  158.         }
  159.         else if(itor->IsVariable())
  160.         {
  161.             bool bFound = false;
  162.             for(int i = 0; i < m_vecVariable.size(); i++)
  163.             {
  164.                 if(m_bCaseSensitive)
  165.                 {
  166.                     if(strcmp(m_vecVariable[i].c_str(), itor->GetVariable()) == 0)
  167.                     {
  168.                         bFound = true;
  169.                         break;
  170.                     }
  171.                 }
  172.                 else
  173.                 {
  174.                     if(stricmp(m_vecVariable[i].c_str(), itor->GetVariable()) == 0)
  175.                     {
  176.                         bFound = true;
  177.                         break;
  178.                     }
  179.                 }
  180.             }
  181.             if(!bFound)
  182.                 m_vecVariable.push_back(itor->GetVariable());
  183.         }
  184.     }
  185.  
  186.     // If there are fewer than 255 unique tokens of a given type, then we can 
  187.     // index that type with a byte instead of a word.  Might as well save space 
  188.     // where we can, eh?
  189.     if(m_vecKeyword.size() > 255)
  190.         m_bWordKeywordIndex = true;
  191.     if(m_vecOperator.size() > 255)
  192.         m_bWordOperatorIndex = true;
  193.     if(m_vecVariable.size() > 255)
  194.         m_bWordVariableIndex = true;
  195. }
  196.  
  197. //------------------------------------------------------------------------//
  198. void TokenFile::WriteTables()
  199. {
  200.     // Write the number of entries in each table, 
  201.     // and then write the strings sequentially.  
  202.     int index;
  203.     WriteWord(m_vecKeyword.size());
  204.     for(index = 0; index < m_vecKeyword.size(); index++)
  205.         WriteString(m_vecKeyword[index]);
  206.     WriteWord(m_vecOperator.size());
  207.     for(index = 0; index < m_vecOperator.size(); index++)
  208.         WriteString(m_vecOperator[index]);
  209.     WriteWord(m_vecVariable.size());
  210.     for(index = 0; index < m_vecVariable.size(); index++)
  211.         WriteString(m_vecVariable[index]);
  212. }
  213.  
  214. //------------------------------------------------------------------------//
  215. void TokenFile::WriteTokens()
  216. {
  217.     
  218.     int index;
  219.     for(TokenListItor itor = m_pTokenList->begin(); itor != m_pTokenList->end(); ++itor)
  220.     {
  221.         // Write the token type
  222.         WriteByte(itor->GetType());
  223.         switch(itor->GetType())
  224.         {
  225.         case Token::KEYWORD:
  226.             for(index = 0; index < m_vecKeyword.size(); index++)
  227.             {
  228.                 if(m_bCaseSensitive)
  229.                 {
  230.                     if(strcmp(itor->GetKeyword(), m_vecKeyword[index].c_str()) == 0)
  231.                     {
  232.                         if(m_bWordKeywordIndex)
  233.                             WriteWord(index);
  234.                         else
  235.                             WriteByte(index);
  236.                         break;
  237.                     }
  238.                 }
  239.                 else
  240.                 {
  241.                     if(stricmp(itor->GetKeyword(), m_vecKeyword[index].c_str()) == 0)
  242.                     {
  243.                         if(m_bWordKeywordIndex)
  244.                             WriteWord(index);
  245.                         else
  246.                             WriteByte(index);
  247.                         break;
  248.                     }
  249.                 }
  250.             }
  251.             break;
  252.  
  253.         case Token::OPERATOR:
  254.             for(index = 0; index < m_vecOperator.size(); index++)
  255.             {
  256.                 if(m_bCaseSensitive)
  257.                 {
  258.                     if(strcmp(itor->GetOperator(), m_vecOperator[index].c_str()) == 0)
  259.                     {
  260.                         if(m_bWordOperatorIndex)
  261.                             WriteWord(index);
  262.                         else
  263.                             WriteByte(index);
  264.                         break;
  265.                     }
  266.                 }
  267.                 else
  268.                 {
  269.                     if(stricmp(itor->GetOperator(), m_vecOperator[index].c_str()) == 0)
  270.                     {
  271.                         if(m_bWordOperatorIndex)
  272.                             WriteWord(index);
  273.                         else
  274.                             WriteByte(index);
  275.                         break;
  276.                     }
  277.                 }
  278.             }
  279.             break;
  280.  
  281.         case Token::VARIABLE:
  282.             for(index = 0; index < m_vecVariable.size(); index++)
  283.             {
  284.                 if(m_bCaseSensitive)
  285.                 {
  286.                     if(strcmp(itor->GetVariable(), m_vecVariable[index].c_str()) == 0)
  287.                     {
  288.                         if(m_bWordVariableIndex)
  289.                             WriteWord(index);
  290.                         else
  291.                             WriteByte(index);
  292.                         break;
  293.                     }
  294.                 }
  295.                 else
  296.                 {
  297.                     if(stricmp(itor->GetVariable(), m_vecVariable[index].c_str()) == 0)
  298.                     {
  299.                         if(m_bWordVariableIndex)
  300.                             WriteWord(index);
  301.                         else
  302.                             WriteByte(index);
  303.                         break;
  304.                     }
  305.                 }
  306.             }
  307.             break;
  308.  
  309.         case Token::STRING:
  310.             WriteString(itor->GetString());
  311.             break;
  312.  
  313.         case Token::INTEGER:
  314.             WriteDword(itor->GetInteger());
  315.             break;
  316.  
  317.         case Token::REAL:
  318.             WriteDouble(itor->GetReal());
  319.             break;
  320.  
  321.         case Token::BOOLEAN:
  322.             WriteByte(itor->GetBoolean());
  323.             break;
  324.  
  325.         case Token::VECTOR:
  326.             WriteVector(itor->GetVector());
  327.             break;
  328.  
  329.         case Token::T_GUID:
  330.             WriteGuid(itor->GetGuid());
  331.             break;
  332.  
  333.         };
  334.     }
  335. }
  336.  
  337.  
  338. //------------------------------------------------------------------------//
  339. void TokenFile::WriteString(std::string sData)
  340. {
  341.     // Since a word is used as the data length, this implies a maximum
  342.     // string length of 65,535 characters, which shouldn't be a problem
  343.     // for most normal use.
  344.     size_t size = sData.length();
  345.     WriteWord(sData.length());
  346.     for(int i = 0; i < sData.length(); i++)
  347.         m_queBuffer.push(sData[i]);
  348. }
  349.  
  350. //------------------------------------------------------------------------//
  351. void TokenFile::WriteDword(DWORD dwData)
  352. {
  353.     // Note the dependence upon byte ordering - important if porting code
  354.     BYTE* pByte = (BYTE*)&dwData;
  355.     for(int i = 0; i < 4; i++)
  356.         m_queBuffer.push(*pByte++);
  357. }
  358.  
  359. //------------------------------------------------------------------------//
  360. void TokenFile::WriteWord(WORD wData)
  361. {
  362.     // Note the dependence upon byte ordering - important if porting code
  363.     BYTE* pByte = (BYTE*)&wData;
  364.     m_queBuffer.push(*pByte++);
  365.     m_queBuffer.push(*pByte++);
  366. }
  367.  
  368. //------------------------------------------------------------------------//
  369. void TokenFile::WriteByte(BYTE byteData)
  370. {
  371.     m_queBuffer.push(byteData);
  372. }
  373.  
  374. //------------------------------------------------------------------------//
  375. void TokenFile::WriteDouble(double dData)
  376. {
  377.     // Note the dependence upon byte ordering - important if porting code
  378.     BYTE* pByte = (BYTE*)&dData;
  379.     for(int i = 0; i < 8; i++)
  380.         m_queBuffer.push(*pByte++);
  381. }
  382.  
  383. //------------------------------------------------------------------------//
  384. void TokenFile::WriteVector(TokenVector3D &vData)
  385. {
  386.     // Note the dependence upon byte ordering - important if porting code
  387.     BYTE* pByte = (BYTE*)&vData;
  388.     for(int i = 0; i < 12; i++)
  389.         m_queBuffer.push(*pByte++);
  390. }
  391.  
  392. //------------------------------------------------------------------------//
  393. void TokenFile::WriteGuid(GUID &guidData)
  394. {
  395.     // Note the dependence upon byte ordering - important if porting code
  396.     BYTE* pByte = (BYTE*)&guidData;
  397.     for(int i = 0; i < 16; i++)
  398.         m_queBuffer.push(*pByte++);
  399. }
  400.  
  401.  
  402.  
  403.  
  404. //------------------------------------------------------------------------//
  405. bool TokenFile::Read(istream& Input, TokenList* pTokenList)
  406. {
  407.     Clear();
  408.     if(pTokenList == NULL)
  409.     {
  410.         return Error::Handle("Must have a valid token list to operate on.\n");
  411.     }
  412.     
  413.     m_pTokenList = pTokenList;
  414.  
  415.     if(!Input.good())
  416.         return Error::Handle("ERROR: file can't be opened for parsing.\n");
  417.  
  418.     // clear the queue
  419.     while(!m_queBuffer.empty())
  420.         m_queBuffer.pop();
  421.  
  422.     // read in the entire file and store in in the queue buffer
  423.     int iData = Input.get();
  424.     while(Input.good())
  425.     {
  426.         m_queBuffer.push(BYTE(iData));
  427.         iData = Input.get();
  428.     }
  429.  
  430.     if(!ReadHeader())
  431.         return Error::Handle("Not a valid pre-compiled script file.");
  432.  
  433.     if(!ReadTables())
  434.         return Error::Handle("Could not read script token table");
  435.  
  436.     if(!ReadTokens())
  437.         return Error::Handle("Could not read script token table");
  438.  
  439.     return true;
  440. }
  441.  
  442. //------------------------------------------------------------------------//
  443. bool TokenFile::Read(string sFilename, TokenList* pTokenList)
  444. {
  445.     ifstream File;
  446.  
  447.     if(pTokenList == NULL)
  448.         return Error::Handle("Function requirest a valid token list");
  449.  
  450.     File.open(sFilename.c_str(), ios::binary);
  451.  
  452.     if( !File.good() )
  453.         return Error::Handle("ERROR: file %s can't be opened for parsing.\n",(const char*)sFilename.c_str());
  454.  
  455.     return Read(File, pTokenList);
  456. }
  457.  
  458.  
  459. //------------------------------------------------------------------------//
  460. bool TokenFile::ReadHeader()
  461. {
  462.     char szHeader[8];
  463.     for(int i = 0; i < 7; i++)
  464.     {
  465.         szHeader[i] = m_queBuffer.front();
  466.         m_queBuffer.pop();
  467.     }
  468.     szHeader[7] = NULL;
  469.     if(strcmp(szHeader, PCS_HEADER) != 0)
  470.         return Error::Handle("Header failed check");
  471.  
  472.     DWORD dwMajor = ReadWord();
  473.     DWORD dwMinor = ReadWord();
  474.     if(dwMajor > PCS_MAJOR_VERSION)
  475.         return Error::Handle("Incompatible file version");
  476.  
  477.     return true;
  478. }
  479.  
  480. //------------------------------------------------------------------------//
  481. bool TokenFile::ReadTables()
  482. {
  483.     int index;
  484.  
  485.     // Read in the keyword table
  486.     WORD wKeywordSize = ReadWord();
  487.     m_vecKeyword.reserve((int)wKeywordSize);
  488.     if(m_vecKeyword.size() > 255)
  489.         m_bWordKeywordIndex = true;
  490.     for(index = 0; index < wKeywordSize; index++)
  491.         m_vecKeyword.push_back(ReadString());
  492.  
  493.     // Read in the operator table
  494.     WORD wOperatorSize = ReadWord();
  495.     m_vecOperator.reserve((int)wOperatorSize);
  496.     if(m_vecOperator.size() > 255)
  497.         m_bWordOperatorIndex = true;
  498.     for(index = 0; index < wOperatorSize; index++)
  499.         m_vecOperator.push_back(ReadString());
  500.  
  501.     // Read in the variable table
  502.     WORD wVariableSize = ReadWord();
  503.     m_vecVariable.reserve((int)wVariableSize);
  504.     if(m_vecVariable.size() > 255)
  505.         m_bWordVariableIndex = true;
  506.     for(index = 0; index < wVariableSize; index++)
  507.         m_vecVariable.push_back(ReadString());
  508.  
  509.     return true;
  510. }
  511.  
  512. //------------------------------------------------------------------------//
  513. bool TokenFile::ReadTokens()
  514. {
  515.     // first read in the token type
  516.     Token::TOKEN_TYPE type;
  517.     Token tok;
  518.  
  519.     while(!m_queBuffer.empty())
  520.     {
  521.         // first read in the token type
  522.         type = (Token::TOKEN_TYPE)ReadByte();
  523.  
  524.         switch(type)
  525.         {
  526.         case Token::KEYWORD:
  527.             if(m_bWordKeywordIndex)
  528.             {
  529.                 WORD index = ReadWord();
  530.                 assert(index < m_vecKeyword.size());
  531.                 tok.InitKeyword(m_vecKeyword[index].c_str());
  532.             }
  533.             else
  534.             {
  535.                 BYTE index = ReadByte();
  536.                 assert(index < m_vecKeyword.size());
  537.                 tok.InitKeyword(m_vecKeyword[index].c_str());
  538.             }
  539.             break;
  540.  
  541.         case Token::OPERATOR:
  542.             if(m_bWordOperatorIndex)
  543.             {
  544.                 WORD index = ReadWord();
  545.                 assert(index < m_vecOperator.size());
  546.                 tok.InitOperator(m_vecOperator[index].c_str());
  547.             }
  548.             else
  549.             {
  550.                 BYTE index = ReadByte();
  551.                 assert(index < m_vecOperator.size());
  552.                 tok.InitOperator(m_vecOperator[index].c_str());
  553.             }
  554.             break;
  555.  
  556.         case Token::VARIABLE:
  557.             if(m_bWordVariableIndex)
  558.             {
  559.                 WORD index = ReadWord();
  560.                 assert(index < m_vecVariable.size());
  561.                 tok.InitVariable(m_vecVariable[index].c_str());
  562.             }
  563.             else
  564.             {
  565.                 BYTE index = ReadByte();
  566.                 assert(index < m_vecVariable.size());
  567.                 tok.InitVariable(m_vecVariable[index].c_str());
  568.             }
  569.             break;
  570.  
  571.         case Token::STRING:
  572.             tok.InitString(ReadString().c_str());
  573.             break;
  574.  
  575.         case Token::INTEGER:
  576.             tok.InitInteger((int)ReadDword());
  577.             break;
  578.  
  579.         case Token::REAL:
  580.             tok.InitReal(ReadDouble());
  581.             break;
  582.  
  583.         case Token::BOOLEAN:
  584.             tok.InitBoolean((ReadByte() != 0) ? true : false);
  585.             break;
  586.  
  587.         case Token::VECTOR:
  588.             tok.InitVector(ReadVector());
  589.             break;
  590.  
  591.         case Token::T_GUID:
  592.             tok.InitGuid(ReadGuid());
  593.             break;
  594.  
  595.         default:
  596.             return Error::Handle("Format error in pre-compiled file.");
  597.         };
  598.  
  599.         m_pTokenList->push_back(tok);
  600.         tok.Term();
  601.     }
  602.     return true;
  603. }
  604.  
  605. //------------------------------------------------------------------------//
  606. // Basic types
  607. string TokenFile::ReadString()
  608. {
  609.     char* pszData;
  610.     WORD wSize = ReadWord();
  611.     pszData = new char[(int)wSize + 1];
  612.     for(int i = 0; i < (int)wSize; i++)
  613.     {
  614.         pszData[i] = m_queBuffer.front();
  615.         m_queBuffer.pop();
  616.     }
  617.     pszData[(int)wSize] = NULL;
  618.     string sData(pszData);
  619.     delete[] pszData;
  620.     return sData;
  621. }
  622.  
  623. //------------------------------------------------------------------------//
  624. DWORD TokenFile::ReadDword()
  625. {
  626.     DWORD dwData;
  627.     PBYTE p = (PBYTE)&dwData;
  628.     for(int i = 0; i < 4; i++)
  629.     {
  630.         *p++ = m_queBuffer.front();
  631.         m_queBuffer.pop();
  632.     }
  633.     return dwData;
  634. }
  635.  
  636. //------------------------------------------------------------------------//
  637. WORD TokenFile::ReadWord()
  638. {
  639.     WORD wData;
  640.     PBYTE p = (PBYTE)&wData;
  641.     *p++ = m_queBuffer.front();
  642.     m_queBuffer.pop();
  643.     *p++ = m_queBuffer.front();
  644.     m_queBuffer.pop();
  645.     return wData;
  646. }
  647.  
  648. //------------------------------------------------------------------------//
  649. BYTE TokenFile::ReadByte()
  650. {
  651.     BYTE byteData = m_queBuffer.front();
  652.     m_queBuffer.pop();
  653.     return byteData;
  654. }
  655.  
  656. //------------------------------------------------------------------------//
  657. double TokenFile::ReadDouble()
  658. {
  659.     double dData;
  660.     PBYTE p = (PBYTE)&dData;
  661.     for(int i = 0; i < 8; i++)
  662.     {
  663.         *p++ = m_queBuffer.front();
  664.         m_queBuffer.pop();
  665.     }
  666.     return dData;
  667. }
  668.  
  669. //------------------------------------------------------------------------//
  670. TokenVector3D TokenFile::ReadVector()
  671. {
  672.     TokenVector3D vData;
  673.     PBYTE p = (PBYTE)&vData;
  674.     for(int i = 0; i < 12; i++)
  675.     {
  676.         *p++ = m_queBuffer.front();
  677.         m_queBuffer.pop();
  678.     }
  679.     return vData;
  680. }
  681.  
  682. //------------------------------------------------------------------------//
  683. GUID TokenFile::ReadGuid()
  684. {
  685.     GUID guidData;
  686.     PBYTE p = (PBYTE)&guidData;
  687.     for(int i = 0; i < 16; i++)
  688.     {
  689.         *p++ = m_queBuffer.front();
  690.         m_queBuffer.pop();
  691.     }
  692.     return guidData;
  693. }
  694.  
  695.  
  696.  
  697.  
  698.