示例#1
0
bool IACFile::Read(wxInputStream &stream) {
    bool isok = false;  // true if minimum one token was read from file
    Invalidate();
    wxString token;
    m_tokensI = 0;
    if (stream.IsOk()) {
        for (;;) {
            token = ReadToken(stream);
            if (!token.IsEmpty()) {
                m_tokens.Add(token);
                m_tokensI++;
                isok = true;
            } else {
                break;
            }
        }
    }
    m_tokensI = 0;

    //    for (std::vector<size_t>::iterator it = m_newlineTokens.begin(); it != m_newlineTokens.end(); ++it)
    //    {
    //        wxMessageBox( wxString::Format( _T("ID: %i :"), *it ) + m_tokens[*it] );
    //    }

    if (isok) {
        // decode tokens if some were found
        isok = Decode();
    }
    m_isok = isok;
    return isok;
}
示例#2
0
文件: http.cpp 项目: tvo/springlobby
bool wxCurlHTTP::Put(wxInputStream& buffer, const wxString& szRemoteFile /*= wxEmptyString*/)
{
    curl_off_t iSize = 0;

    if(m_pCURL && buffer.IsOk())
    {
        SetCurlHandleToDefaults(szRemoteFile);

        iSize = buffer.GetSize();

        if(iSize == (~(size_t)0))	// wxCurlHTTP does not know how to upload unknown length streams.
            return false;

        SetOpt(CURLOPT_UPLOAD, TRUE);
        SetOpt(CURLOPT_PUT, TRUE);
        SetStreamReadFunction(buffer);
        SetOpt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)iSize);
        SetStringWriteFunction(m_szResponseBody);

        if(Perform())
        {
            return IsResponseOk();
        }
    }

    return false;
}
示例#3
0
FbImportBook::FbImportBook(FbImportThread & owner, wxInputStream & in, const wxString & filename)
	: m_parser(NULL)
	, m_database(*owner.GetDatabase())
	, m_filename(owner.GetRelative(filename))
	, m_filepath(owner.GetAbsolute(filename))
	, m_filetype(Ext(m_filename))
	, m_message(filename)
	, m_filesize(in.GetLength())
	, m_archive(0)
	, m_ok(false)
{
	wxLogMessage(_("Import file %s"), m_filename.c_str());
	m_ok = in.IsOk();
	if (!m_ok) return;

	if (m_filetype == wxT("fb2")) {
		m_parser = new FbImportReaderFB2(in, true);
		m_md5sum = m_parser->GetMd5();
	} else if (m_filetype == wxT("epub")) {
		m_md5sum = CalcMd5(in);
		in.SeekI(0);
		wxString rootfile = FbRootReaderEPUB(in).GetRoot();
		in.SeekI(0);
		m_parser = new FbDataReaderEPUB(in, rootfile);
	} else {
		m_md5sum = CalcMd5(in);
	}
}
示例#4
0
文件: ftp.cpp 项目: KastB/OpenCPN
bool wxCurlFTP::Put(wxInputStream& buffer, const wxString& szRemoteFile /*= wxEmptyString*/)
{
	curl_off_t iSize = 0;

	if(m_pCURL && buffer.IsOk())
	{
		SetCurlHandleToDefaults(szRemoteFile);

		iSize = buffer.GetSize();

		if(iSize == (~(ssize_t)0))
			return false;

		SetOpt(CURLOPT_UPLOAD, TRUE);
		SetStreamReadFunction(buffer);
		SetOpt(CURLOPT_INFILESIZE_LARGE, iSize);

		if(Perform())
		{
			return ((m_iResponseCode > 199) && (m_iResponseCode < 300));
		}
	}

	return false;
}
示例#5
0
wxString IACFile::ReadToken(wxInputStream &file) {
    // 0 = read chars until digit
    // 1 = read digits until no digit
    // 2 = token found
    wxString token = wxEmptyString;

    int mode = 0;

    while (file.IsOk() && mode != 2) {
        int c = file.GetC();

        if (c != wxEOF && c <= 128) {
            if (c == '\n' && m_tokensI > 0) {
                m_newlineTokens.push_back(m_tokensI + 1);
            }
            m_RawData.Append((char)c);
            switch (mode) {
                case 0:
                    if (isdigit(c)) {
                        token.Append((char)c);
                        mode = 1;
                    }
                    break;
                case 1:
                    if (isdigit(c) || c == '/') {
                        token.Append((char)c);
                    } else {
                        if (token.Len() == 5) {
                            // token found!!
                            mode = 2;
                        } else {
                            token.Empty();
                        }
                    }
                    break;
                    /* this is dead code
                                case 2:
                                    mode = 0;
                                    break;
                    */
            }  // case
        }
    }  // while
    if (mode != 2) {
        token.Empty();
    }

    return token;
}
示例#6
0
bool udSettings::DeserializeFromXml(wxInputStream& instream)
{
	if( instream.IsOk() )
	{
		if( !wxXmlSerializer::DeserializeFromXml( instream ) )
		{
			RemoveAll();
			this->CreateCategories();
		}
		else
			return true;
	}
	else
		this->CreateCategories();
		
	return false;
}
示例#7
0
LifeReader::LifeReader(wxInputStream& is)
{
    wxBufferedInputStream buff_is(is);
    wxTextInputStream     text_is(buff_is);
    wxString              line, rest;

    // check stream
    m_ok = is.IsOk();
    LIFE_CHECKVAL(_("Couldn't read any data"));

    // read signature
    m_ok = text_is.ReadLine().Contains(wxT("#Life 1.05"));
    LIFE_CHECKVAL(_("Error reading signature. Not a Life pattern?"));

    // read description
    m_description = wxEmptyString;
    line = text_is.ReadLine();
    while (buff_is.IsOk() && line.StartsWith(wxT("#D"), &rest))
    {
        m_description += rest.Trim(false);
        m_description += wxT("\n");
        line = text_is.ReadLine();
    }

    m_ok = buff_is.IsOk();
    LIFE_CHECKVAL(_("Unexpected EOF while reading description"));

    // read rules
    m_ok = line.StartsWith(wxT("#N"));
    LIFE_CHECKVAL(_("Sorry, non-conway rules not supported yet"));

    // read shape
    while (buff_is.IsOk())
    {
        line = ( text_is.ReadLine() ).Trim();

        if (!line.empty())
        {
            if (line.StartsWith(wxT("#P "), &rest))
                m_shape.Add(rest);
            else
                m_shape.Add(line);
        }
    }
}
示例#8
0
文件: chm.cpp 项目: BloodRedd/gamekit
/**
 * Creates a Stream pointing to a virtual file in
 * the current archive
 */
bool wxChmInputStream::CreateFileStream(const wxString& pattern)
{
    wxFileInputStream * fin;
    wxString tmpfile = wxFileName::CreateTempFileName(wxT("chmstrm"));

    if ( tmpfile.empty() )
    {
        wxLogError(_("Could not create temporary file '%s'"), tmpfile.c_str());
        return false;
    }

    // try to extract the file
    if ( m_chm->Extract(pattern, tmpfile) <= 0 )
    {
        wxLogError(_("Extraction of '%s' into '%s' failed."),
                   pattern.c_str(), tmpfile.c_str());
        if ( wxFileExists(tmpfile) )
            wxRemoveFile(tmpfile);
        return false;
    }
    else
    {
        // Open a filestream to extracted file
        fin = new wxFileInputStream(tmpfile);
        if (!fin->IsOk())
            return false;

        m_size = fin->GetSize();
        m_content = (char *) malloc(m_size+1);
        fin->Read(m_content, m_size);
        m_content[m_size]='\0';

        wxRemoveFile(tmpfile);

        delete fin;

        m_contentStream = new wxMemoryInputStream (m_content, m_size);

        return m_contentStream->IsOk();
    }
}
示例#9
0
bool GetToken(wxInputStream& input, wxString& result, unsigned int& lineNumber)
{

    result.Empty();

    SkipWhitespace(input, lineNumber);

    // Reached the end of the file.
    if (input.Eof())
    {
        return false;
    }

    char c = input.GetC();

    if (c == '\"')
    {

        // Quoted string, search for the end quote.

        do
        {
            result += c;
            c = input.GetC();
        }
        while (input.IsOk() && c != '\"');

        result += c;
        return true;

    }

    char n = input.Peek();

    if (IsDigit(c) || (c == '.' && IsDigit(n)) || (c == '-' && IsDigit(n)))
    {

        bool hasDecimal = false;

        while (!IsSpace(c))
        {

            result.Append(c);

            if (input.Eof())
            {
                return true;
            }

            c = input.Peek();

            if (!IsDigit(c) && c != '.')
            {
                return true;
            }

            input.GetC();

            if (c == '\n')
            {
                ++lineNumber;
                return true;
            }

        }

    }
    else
    {

        if (IsSymbol(c))
        {
            result = c;
            return true;
        }

        while (!IsSpace(c) && !input.Eof())
        {

            result.Append(c);

            if (IsSymbol(input.Peek()))
            {
                break;
            }

            c = input.GetC();

            if (c == '\n')
            {
                ++lineNumber;
                return true;
            }

        }

    }

    return true;

}
示例#10
0
 bool IsOk() const
     { if (m_pStream == NULL) return FALSE; return m_pStream->IsOk(); }
示例#11
0
void SymbolParserThread::ParseFileSymbols(wxInputStream& input, std::vector<Symbol*>& symbols)
{

    if (!input.IsOk())
    {
        return;
    }

    wxString token;

    unsigned int lineNumber = 1;

    while (GetToken(input, token, lineNumber))
    {
        if (token == "function")
        {

            unsigned int defLineNumber = lineNumber;

            // Lua functions can have these forms:
            //    function (...)
            //    function Name (...)
            //    function Module.Function (...)
            //    function Class:Method (...)

            wxString t1;
            if (!GetToken(input, t1, lineNumber)) break;

            if (t1 == "(")
            {
                // The form function (...) which doesn't have a name. If we
                // were being really clever we could check to see what is being
                // done with this value, but we're not.
                continue;
            }

            wxString t2;
            
            if (!GetToken(input, t2, lineNumber)) break;

            if (t2 == "(")
            {
                // The form function Name (...).
                symbols.push_back(new Symbol("", t1, defLineNumber));
            }
            else
            {
                
                wxString t3;
                if (!GetToken(input, t3, lineNumber)) break;

                if (t2 == "." || t2 == ":")
                {
                    symbols.push_back(new Symbol(t1, t3, defLineNumber));
                }

            }


        }
    }

}
示例#12
0
bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
{
    UnRef();

    char anim_type[12];
    switch (type)
    {
    case wxANIMATION_TYPE_GIF:
        strcpy(anim_type, "gif");
        break;

    case wxANIMATION_TYPE_ANI:
        strcpy(anim_type, "ani");
        break;

    default:
        anim_type[0] = '\0';
        break;
    }

    // create a GdkPixbufLoader
    GError *error = NULL;
    GdkPixbufLoader *loader;
    if (type != wxANIMATION_TYPE_INVALID && type != wxANIMATION_TYPE_ANY)
        loader = gdk_pixbuf_loader_new_with_type(anim_type, &error);
    else
        loader = gdk_pixbuf_loader_new();

    if (!loader)
    {
        wxLogDebug(wxT("Could not create the loader for '%s' animation type"), anim_type);
        return false;
    }

    // connect to loader signals
    g_signal_connect(loader, "area-updated", G_CALLBACK(gdk_pixbuf_area_updated), this);

    guchar buf[2048];
    while (stream.IsOk())
    {
        // read a chunk of data
        stream.Read(buf, sizeof(buf));

        // fetch all data into the loader
        if (!gdk_pixbuf_loader_write(loader, buf, stream.LastRead(), &error))
        {
            gdk_pixbuf_loader_close(loader, &error);
            wxLogDebug(wxT("Could not write to the loader"));
            return false;
        }
    }

    // load complete
    if (!gdk_pixbuf_loader_close(loader, &error))
    {
        wxLogDebug(wxT("Could not close the loader"));
        return false;
    }

    // wait until we get the last area_updated signal
    return true;
}
示例#13
0
bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
{
    UnRef();

    char anim_type[12];
    switch (type)
    {
    case wxANIMATION_TYPE_GIF:
        strcpy(anim_type, "gif");
        break;

    case wxANIMATION_TYPE_ANI:
        strcpy(anim_type, "ani");
        break;

    default:
        anim_type[0] = '\0';
        break;
    }

    // create a GdkPixbufLoader
    GError *error = NULL;
    GdkPixbufLoader *loader;
    if (type != wxANIMATION_TYPE_INVALID && type != wxANIMATION_TYPE_ANY)
        loader = gdk_pixbuf_loader_new_with_type(anim_type, &error);
    else
        loader = gdk_pixbuf_loader_new();

    if (!loader ||
        error != NULL)  // even if the loader was allocated, an error could have happened
    {
        wxLogDebug(wxT("Could not create the loader for '%s' animation type: %s"),
                   anim_type, error->message);
        return false;
    }

    // connect to loader signals
    g_signal_connect(loader, "area-updated", G_CALLBACK(gdk_pixbuf_area_updated), this);

    guchar buf[2048];
    bool data_written = false;
    while (stream.IsOk())
    {
        // read a chunk of data
        if (!stream.Read(buf, sizeof(buf)) &&
            stream.GetLastError() != wxSTREAM_EOF)   // EOF is OK for now
        {
            // gdk_pixbuf_loader_close wants the GError == NULL
            gdk_pixbuf_loader_close(loader, NULL);
            return false;
        }

        // fetch all data into the loader
        if (!gdk_pixbuf_loader_write(loader, buf, stream.LastRead(), &error))
        {
            wxLogDebug(wxT("Could not write to the loader: %s"), error->message);

            // gdk_pixbuf_loader_close wants the GError == NULL
            gdk_pixbuf_loader_close(loader, NULL);
            return false;
        }

        data_written = true;
    }

    if (!data_written)
    {
        wxLogDebug("Could not read data from the stream...");
        return false;
    }

    // load complete: gdk_pixbuf_loader_close will now check if the data we
    // wrote inside the pixbuf loader does make sense and will give an error
    // if it doesn't (because of a truncated file, corrupted data or whatelse)
    if (!gdk_pixbuf_loader_close(loader, &error))
    {
        wxLogDebug(wxT("Could not close the loader: %s"), error->message);
        return false;
    }

    // wait until we get the last area_updated signal
    return data_written;
}
/**
 * Calculates the checksums from the given stream.
 *
 * @param  in         Input stream from which the data will be extracted to
 *                    compute the checksum. The data are extracted until the end
 *                    of the stream is reached.
 * @param  checksums  Array of checksums to calculate.
 * @param  sumValues  The calculated values of the checksums from the input
 *                    stream. The array is erased first before adding results.
 *                    On success <CODE>ArrayChecksum.GetCount() == sumValues.GetCount()</CODE>,
 *                    on failure, <CODE>sumValues</CODE> should be empty.
 * @return <UL>
 *           <LI><CODE>Ok</CODE> if the checksum has been successfully calculated.</Li>
 *           <LI><CODE>ReadError</CODE> if a read error has occured.</LI>
 *           <LI><CODE>Canceled</CODE> if the user has canceled the calculation.</LI>
 *         </UL>
 */
ChecksumCalculator::State ChecksumCalculator::calculate(wxInputStream& in,
                                                 const ArrayChecksum& checksums,
                                                       wxArrayString& sumValues)
{
  // Check if the input stream is valid.
  if (!in.IsOk())
    return ReadError;
  
  // Check if at least a checksum instance is OK.
  bool aInstanceOK = false;
  size_t i = 0;
  size_t s = checksums.GetCount();
  while (!aInstanceOK && i < s)
    if (checksums[i] != NULL)
      aInstanceOK = true;
    else
      i++;
  if (!aInstanceOK)
    return ReadError;
  
  // Initializes the buffer.
  const size_t bufSize = getBufferSize();
  wxByte* buff = new wxByte[bufSize];

  // Calculating the checksum.
  ChecksumProgress* p = getChecksumProgress();
  bool canceled = false;
  size_t read;
  wxStreamError lastError = wxSTREAM_NO_ERROR;
  s = checksums.GetCount();
  for (i = 0; i < s; i++)
    if (checksums[i] != NULL)
      checksums[i]->reset();
  while (!canceled && !in.Eof() && lastError == wxSTREAM_NO_ERROR)
  {
    in.Read(buff, bufSize);
    read = in.LastRead();
    if (read > 0 && read <= bufSize)
    {
      for (i = 0; i < s; i++)
        if (checksums[i] != NULL)
          checksums[i]->update(buff, read);
      if (p != NULL)
        p->update(read, canceled);
    }
    lastError = in.GetLastError();
  }

  // Cleans-up the memory
  delete[] buff;
  
  if (canceled)
    return CanceledByUser;
  
  if (lastError != wxSTREAM_NO_ERROR && lastError != wxSTREAM_EOF)
    return ReadError;
    
  sumValues.Empty();
  for (i = 0; i < s; i++)
    if (checksums[i] != NULL)
      sumValues.Add(checksums[i]->getValue());
    else
      sumValues.Add(wxEmptyString);

  return Ok;
}
示例#15
0
void SymbolParserThread::ParseFileSymbols(wxInputStream& input, std::vector<Symbol*>& symbols)
{

    if (!input.IsOk())
    {
        return;
    }

    wxString token;

    unsigned int lineNumber = 1;

    Symbol *return_symbol = nullptr;

    wxStack<Symbol *> symStack;
    symStack.push(nullptr);

    std::vector<Token> tokens;
    while (GetToken(input, token, lineNumber))
    {
      tokens.emplace_back(token, lineNumber);
    }

    for (unsigned current_token = 0; current_token < tokens.size(); ++current_token)
    {
      token = tokens[current_token].token;
      lineNumber = tokens[current_token].lineNumber;

      if (token == "function")
      {
        unsigned int defLineNumber = lineNumber;
        Symbol *function = nullptr;

        // Lua functions can have these forms:
        //    function (...)
        //    function Name (...)
        //    function Module.Function (...)
        //    function Class:Method (...)

        wxString t1;
        if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;

        if (t1 == "(")
        {
          // The form function (...) which doesn't have a name. If we
          // were being really clever we could check to see what is being
          // done with this value, but we're not.
          continue;
        }

        wxString t2;

        if (!GetNextToken(tokens, t2, lineNumber, current_token)) break;

        if (t2 == "(")
        {
          function = new Symbol(symStack.top(), t1, defLineNumber);

          if (return_symbol)
          {
            function->typeSymbol = return_symbol;
            return_symbol = nullptr;
          }

          // The form function Name (...).
          symbols.push_back(function);
        }
        else
        {

          wxString t3;
          if (!GetNextToken(tokens, t3, lineNumber, current_token)) break;

          if (t2 == "." || t2 == ":")
          {
            Symbol *module = GetSymbol(t1, symbols);
            if (module == nullptr)
            {
              module = new Symbol(symStack.top(), t1, defLineNumber, SymbolType::Module);
              symbols.push_back(module);
            }

            function = new Symbol(module, t3, defLineNumber);
            if (return_symbol)
            {
              function->typeSymbol = return_symbol;
              return_symbol = nullptr;
            }

            symbols.push_back(function);
          }

        }


        if (function)
          symStack.push(function);

      }
      else if (token == "decodadef")
      {
        //A decodadef will be in the form:
        //decodadef name { Definitions }
        //decodadef name ret

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;

        wxString t1 = PeekNextToken(tokens, current_token, lineNumber);
        if (t1 == "{")
        {
          if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;
          //outputWin->OutputMessage("Processing " + moduleName);

          Symbol *module = GetSymbol(moduleName, symbols);
          if (module == nullptr)
          {
            module = new Symbol(symStack.top(), moduleName, lineNumber, SymbolType::Type);
            symbols.push_back(module);
          }

          DecodaDefRecursive(symbols, lineNumber, module, tokens, current_token);
        }
        else
        {
          DecodaDefFunction(symbols, lineNumber, nullptr, tokens, current_token, moduleName);
        }
      }
      else if (token == "end")
      {
        if (symStack.size() > 1)
          symStack.pop();
      }
      else if (token == "decodaprefix")
      {
        //A decodaprefix will be in the form:
        //decodaprefix Module name

        /*
        decodaprefix this __FILENAME__
        decodaprefix this { Weapon nil }

        */

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;


        Symbol *module = GetSymbol(moduleName, symbols, SymbolType::Prefix);
        if (module == nullptr)
        {
          module = new Symbol(nullptr, moduleName, defLineNumber, SymbolType::Prefix);
          symbols.push_back(module);
        }

        wxString t1;
        if (!GetNextToken(tokens, t1, lineNumber, current_token)) break;

        //List of 
        if (t1 == "{")
        {
          DecodaPrefixRecursive(symbols, lineNumber, module, tokens, current_token);
        }
        else
        {
          Symbol *sym_prefix = new Symbol(module, t1, defLineNumber, SymbolType::Prefix);
          sym_prefix->requiredModule = moduleName;
          symbols.push_back(sym_prefix);
        }
      }
      else if (token == "decodareturn")
      {
        //A decodaprefix will be in the form:
        //decodareturn Module

        unsigned int defLineNumber = lineNumber;

        wxString moduleName;
        if (!GetNextToken(tokens, moduleName, lineNumber, current_token)) break;

        Symbol *module = GetSymbol(moduleName, symbols);
        if (module == nullptr)
        {
          module = new Symbol(symStack.top(), moduleName, lineNumber, SymbolType::Type);
          symbols.push_back(module);
        }

        return_symbol = module;
      }
      else if (token == "=")
      {
        unsigned int defLineNumber = lineNumber;

        //If we find an equal sign, we need to find the left and right hand side
        unsigned start = current_token;

        //First handle +=, -=, *=, /=
        wxString prev = PeekPrevToken(tokens, current_token, lineNumber);
        if (prev == "+" || prev == "-" || prev == "*" || prev == "/")
          GetPrevToken(tokens, prev, lineNumber, current_token);

        wxStack<wxString> lhs_stack;
        wxString lhs;
        if (!GetPrevToken(tokens, lhs, lineNumber, current_token)) break;
        
        lhs_stack.push(lhs);

        int currentLine = lineNumber;

        prev = PeekPrevToken(tokens, current_token, lineNumber);
        while ((prev == "." || prev == ":" || prev == ")" || prev == "]") && lineNumber == currentLine)
        {
          if (prev == "." || prev == ":")
          {
            GetPrevToken(tokens, prev, lineNumber, current_token);
            lhs_stack.push(prev);

            wxString part;
            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            if (part == ")" || part == "]")
            {
              current_token++;
              prev = part;
              continue;
            }

            lhs_stack.push(part);
          }
          else if (prev == ")" || prev == "]")
          {
            GetPrevToken(tokens, prev, lineNumber, current_token);
            lhs_stack.push(prev);

            wxString open;
            wxString close;

            if (prev == ")")
            {
              open = "(";
              close = ")";
            }
            else if (prev == "]")
            {
              open = "[";
              close = "]";
            }


            int parenStack = 0;
            wxString part;
            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            for (;;)
            {
              if (part == close)
                parenStack++;
              if (part == open)
              {
                if (parenStack == 0)
                  break;
                parenStack--;
              }

              lhs_stack.push(part);
              if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            }
            lhs_stack.push(part);

            if (!GetPrevToken(tokens, part, lineNumber, current_token)) return;
            lhs_stack.push(part);
          }

          prev = PeekPrevToken(tokens, current_token, lineNumber);
        }

        //Parse rhs
        current_token = start;

        //First handle +=, -=, *=, /=
        wxString next = PeekNextToken(tokens, current_token, lineNumber);
        bool valid = true;
        for (int i = 0; i < next.size(); ++i)
        {
          if (IsSymbol(next[i]) || IsSpace(next[i]))
          {
            valid = false;
            break;
          }
        }

        wxString rhs;

        if (valid)
        {
          GetNextToken(tokens, next, lineNumber, current_token);
          rhs.Append(next);

          next = PeekNextToken(tokens, current_token, lineNumber);
          while ((next == "." || next == ":" || next == "(" || next == "[") && lineNumber == currentLine)
          {
            if (next == "." || next == ":")
            {
              GetNextToken(tokens, next, lineNumber, current_token);
              rhs.Append(next);

              wxString part;
              if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              rhs.Append(part);
            }
            else if (next == "(" || next == "[")
            {
              GetNextToken(tokens, next, lineNumber, current_token);
              rhs.Append(next);

              wxString open;
              wxString close;

              if (next == "(")
              {
                open = "(";
                close = ")";
              }
              else if (next == "[")
              {
                open = "[";
                close = "]";
              }


              int parenStack = 0;
              wxString part;
              if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              for (;;)
              {
                if (part == open)
                  parenStack++;
                if (part == close)
                {
                  if (parenStack == 0)
                    break;
                  parenStack--;
                }

                rhs.Append(part);
                if (!GetNextToken(tokens, part, lineNumber, current_token)) return;
              }
              rhs.Append(part);
            }

            next = PeekNextToken(tokens, current_token, lineNumber);
          }
        }

        //Build up the strings with the stacks
        if (lhs_stack.size() > 0 && rhs.size() > 0)
        {
          lhs.Empty();

          while (!lhs_stack.empty())
          {
            lhs.Append(lhs_stack.top());
            lhs_stack.pop();
          }

          Symbol *assignment = new Symbol(symStack.top(), lhs, defLineNumber, SymbolType::Assignment);
          assignment->rhs = rhs;
          symbols.push_back(assignment);
        }

        //Reset token
        current_token = start;
      }
    }
}
wxArchive::wxArchive(wxInputStream &stream, size_t version, const wxString &header, bool partialMode)
	: m_writeMode(false)
	, m_idstr(stream)
	, m_partialMode(partialMode)
	, m_otmp(&m_tmpostr)
	, m_odstr(m_otmp)
	, m_itmp(m_tmpistr)
{
    InitAll();

    // all ok, use this stream
    if(stream.IsOk())
    {
	    // now we need to reset the code for
	    // reading to work
	    m_errorCode = wxARCHIVE_ERR_OK;
		m_opened = true;

	    // load header
	    wxString hdr = LoadString();

	    if(IsOk())
	    {
	        // when we have a header to check else ignore and store
	        // for future reference (and writing back maybe?)
	        if(header.IsEmpty() || header.IsSameAs(hdr))
	        {
	            // store header for consulting later
	            m_headerStr = header;

                // check the version number
                size_t ver = LoadUint32();

                if(IsOk())
                {
                    // if version is 0, we accept any version if higher, we
                    // need to see if this stream does not exceed the expected version
                    if(!version || ver <=version)
                    {
                        // this is the point where all is
                        // approved. We can start reading
                        m_version = ver;
						m_status = wxArchiveStatus(m_version, m_headerStr);
                    }
                    else
                    {
                        wxString v1, v2;
                        v1 << version;
                        v2 << ver;

                        LogError(wxARCHIVE_ERR_ILL, wxARCHIVE_ERR_STR_WRONGVERSION_s1_s2, v1, v2);
                    }
                }
                else
                    LogError(wxARCHIVE_ERR_ILL, wxARCHIVE_ERR_STR_NOVERSION);
	        }
	        else
	            LogError(wxARCHIVE_ERR_ILL, wxARCHIVE_ERR_STR_HEADER_s1_s2, header, hdr);
	    }
	    else
	        LogError(wxARCHIVE_ERR_ILL, wxARCHIVE_ERR_STR_NOHEADER_s1, header);
	}
	else
	    LogError(wxARCHIVE_ERR_ILL, wxARCHIVE_ERR_STR_BADISTREAM);
}