string m_printf_buffer; //ovectorstream m_printf_buffer; // persistent buffer for formatted output protected core_text_file(uint32_t openflags) { m_openflags = openflags; m_text_type = text_file_type.OSD; m_back_char_head = 0; m_back_char_tail = 0; m_printf_buffer = ""; }
/*------------------------------------------------- * getc - read a character from a file * -------------------------------------------------*/ public override int getc() { // refresh buffer, if necessary if (m_back_char_head == m_back_char_tail) { // do we need to check the byte order marks? uint64_t pos; if (!tell(out pos)) { if (pos == 0) { size_t readlen; MemoryU8 bom = new MemoryU8(4, true); //std::uint8_t bom[4]; read(new PointerU8(bom), 4, out readlen); if (readlen == 4) { if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf) { m_text_type = text_file_type.UTF8; pos = 3; } else if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xfe && bom[3] == 0xff) { m_text_type = text_file_type.UTF32BE; pos = 4; } else if (bom[0] == 0xff && bom[1] == 0xfe && bom[2] == 0x00 && bom[3] == 0x00) { m_text_type = text_file_type.UTF32LE; pos = 4; } else if (bom[0] == 0xfe && bom[1] == 0xff) { m_text_type = text_file_type.UTF16BE; pos = 2; } else if (bom[0] == 0xff && bom[1] == 0xfe) { m_text_type = text_file_type.UTF16LE; pos = 2; } else { m_text_type = text_file_type.OSD; pos = 0; } } seek((int64_t)pos, SEEK_SET); // FIXME: don't assume seeking is possible, check for errors } } // fetch the next character // FIXME: all of this plays fast and loose with error checking and seeks backwards far too frequently MemoryU8 utf16_buffer = new MemoryU8(UTF16_CHAR_MAX, true); //char16_t utf16_buffer[UTF16_CHAR_MAX]; var uchar = char32_t.MaxValue; //auto uchar = char32_t(~0); switch (m_text_type) { default: case text_file_type.OSD: { MemoryU8 default_buffer = new MemoryU8(16, true); //char default_buffer[16]; size_t readlen; read(new PointerU8(default_buffer), (size_t)default_buffer.Count, out readlen); //read(default_buffer, sizeof(default_buffer), readlen); if (readlen > 0) { //auto const charlen = osd_uchar_from_osdchar(&uchar, default_buffer, readlen / sizeof(default_buffer[0])); uchar = default_buffer[0]; var charlen = 1; seek((int64_t)(charlen * 1) - (int64_t)readlen, SEEK_CUR); //seek(std::int64_t(charlen * sizeof(default_buffer[0])) - readlen, SEEK_CUR); } } break; case text_file_type.UTF8: { MemoryU8 utf8_buffer = new MemoryU8(UTF8_CHAR_MAX, true); //char utf8_buffer[UTF8_CHAR_MAX]; size_t readlen; read(new PointerU8(utf8_buffer), (size_t)utf8_buffer.Count, out readlen); if (readlen > 0) { //auto const charlen = uchar_from_utf8(&uchar, utf8_buffer, readlen / sizeof(utf8_buffer[0])); uchar = utf8_buffer[0]; var charlen = 1; seek((int64_t)(charlen * 1) - (int64_t)readlen, SEEK_CUR); //seek(std::int64_t(charlen * sizeof(utf8_buffer[0])) - readlen, SEEK_CUR); } } break; case text_file_type.UTF16BE: { size_t readlen; read(new PointerU8(utf16_buffer), (size_t)utf16_buffer.Count, out readlen); //read(utf16_buffer, sizeof(utf16_buffer), readlen); if (readlen > 0) { throw new emu_unimplemented(); } } break; case text_file_type.UTF16LE: { size_t readlen; read(new PointerU8(utf16_buffer), (size_t)utf16_buffer.Count, out readlen); //read(utf16_buffer, sizeof(utf16_buffer), readlen); if (readlen > 0) { throw new emu_unimplemented(); } } break; case text_file_type.UTF32BE: { // FIXME: deal with read returning short size_t readlen; MemoryU8 ucharTemp = new MemoryU8(4, true); read(new PointerU8(ucharTemp), 4, out readlen); //read(&uchar, sizeof(uchar), readlen); if (4 == readlen) //if (sizeof(uchar) == readlen) { throw new emu_unimplemented(); } } break; case text_file_type.UTF32LE: { // FIXME: deal with read returning short size_t readlen; MemoryU8 ucharTemp = new MemoryU8(4, true); read(new PointerU8(ucharTemp), 4, out readlen); //read(&uchar, sizeof(uchar), readlen); if (4 == readlen) //if (sizeof(uchar) == readlen) { uchar = little_endianize_int32(ucharTemp.GetUInt32()); } } break; } if (uchar != char32_t.MaxValue) //if (uchar != ~0) { // place the new character in the ring buffer m_back_char_head = 0; m_back_char_tail = utf8_from_uchar(out string back_chars, uchar); //m_back_char_tail = utf8_from_uchar(m_back_chars, std::size(m_back_chars), uchar); back_chars.CopyTo(0, m_back_chars, 0, back_chars.Length); //assert(file->back_char_tail != -1); } } // now read from the ring buffer int result; if (m_back_char_head == m_back_char_tail) { result = EOF; } else { result = m_back_chars[m_back_char_head++]; m_back_char_head %= (int)std.size(m_back_chars); } return(result); }