Exemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////////////
        // Saves BAS file
        public bool Save(Stream in_stream, ProgramStorage in_storage)
        {
            Encoding encoding;

            // set open options based on encoding type
            switch (Encoding)
            {
            case EncodingType.Ansi:
                encoding = new ASCIIEncoding();
                break;

            case EncodingType.Auto:
            case EncodingType.Utf8:
                encoding = new UTF8Encoding();
                break;

            case EncodingType.Unicode:
                encoding = new UnicodeEncoding();
                break;

            default:
                encoding = null;
                break;
            }


            using (StreamWriter bas_file = new StreamWriter(in_stream, encoding))
            {
                // start processing of the memory
                int        current_pos   = 0;
                int        next_line_pos = 0;
                int        line_data_end;
                StatusCode state = StatusCode.Tokenizing;

                BasicLineHeader current_line = new BasicLineHeader();
                current_line.ReadFromMemory(current_pos, in_storage);

                while (current_pos < in_storage.Length && current_line.Length != BAS_PRGEND)
                {
                    // check basic format
                    if (current_line.Length < BasicLineHeader.Size)
                    {
                        bas_file.Write("\n*** Broken BASIC program\n");
                        break;
                    }

                    // set next line pointer
                    next_line_pos = current_pos + current_line.Length;

                    // write line number
                    bas_file.Write("{0,4:d} ", current_line.Number);

                    // decode  line
                    current_pos  += BasicLineHeader.Size;
                    line_data_end = next_line_pos;
                    if (current_pos <= line_data_end - 1 && in_storage.Data[line_data_end - 1] == BAS_LINEND)
                    {
                        line_data_end--;
                    }

                    state = StatusCode.Tokenizing;
                    while (current_pos < line_data_end)
                    {
                        char current_char = (char)in_storage.Data[current_pos];

                        // decode token or character
                        if (state == StatusCode.Tokenizing)
                        {
                            // store tokenized item
                            if (Encoding == EncodingType.Ansi)
                            {
                                bas_file.Write(m_ansi_tokenized_map[current_char]);
                            }
                            else
                            {
                                bas_file.Write(m_unicode_tokenized_map[current_char]);
                            }
                        }
                        else
                        {
                            // store non tokenized item
                            if (Encoding == EncodingType.Ansi)
                            {
                                if (current_char < 0x80)
                                {
                                    bas_file.Write(m_ansi_tokenized_map[current_char]);
                                }
                                else
                                {
                                    bas_file.Write("\\x{0:X2}", current_char);
                                }
                            }
                            else
                            {
                                if (current_char < 0x80)
                                {
                                    bas_file.Write(m_unicode_tokenized_map[current_char]);
                                }
                                else
                                {
                                    bas_file.Write("\\x{0:X2}", current_char);
                                }
                            }
                        }

                        // update status
                        if (current_char == '"')
                        {
                            state ^= StatusCode.Quotation;
                        }
                        else
                        {
                            if (!state.HasFlag(StatusCode.Quotation))
                            {
                                if (current_char == BAS_TOKEN_DATA)
                                {
                                    state |= StatusCode.Data;
                                }
                                else
                                {
                                    if (current_char == BAS_TOKEN_COLON)
                                    {
                                        state &= ~StatusCode.Data;
                                    }
                                    else
                                    {
                                        if (current_char == BAS_TOKEN_COMMENT || current_char == BAS_TOKEN_REM)
                                        {
                                            state |= StatusCode.Remark;
                                        }
                                    }
                                }
                            }
                        }

                        current_pos++;
                    }

                    bas_file.WriteLine();

                    current_pos = next_line_pos;

                    current_line.ReadFromMemory(current_pos, in_storage);
                }

                // write remaining data offset
                int remaining_byte_index = current_pos + 1;                 // +1 beacuse of the BAS_PRGEND byte
                if (remaining_byte_index < in_storage.Length)
                {
                    bas_file.WriteLine("BYTESOFFSET {0}", remaining_byte_index);
                }

                // write remaining data
                int bytes_in_a_line = 0;
                while (remaining_byte_index < in_storage.Length)
                {
                    if (bytes_in_a_line == 0)
                    {
                        bas_file.Write("BYTES ");
                    }

                    bas_file.Write("\\x{0:X2}", in_storage.Data[remaining_byte_index]);

                    remaining_byte_index++;
                    bytes_in_a_line++;

                    // write new line
                    if (bytes_in_a_line > MAX_BYTES_IN_A_LINE)
                    {
                        bas_file.WriteLine();
                        bytes_in_a_line = 0;
                    }
                }
                // new line
                if (bytes_in_a_line > 0)
                {
                    bas_file.WriteLine();
                }

                // write autostart
                if (in_storage.AutoStart)
                {
                    bas_file.WriteLine("AUTOSTART");
                }
            }

            return(true);
        }