示例#1
0
/**
 * Converts two characters into a hex integers
 * and then inserts the integers into the higher
 * and lower bits of the byte
 * @param twoChars - two charcters representing the
 * the hexidecimal nibbles of the byte.
 * @param twoChars - the two characters
 * @return - the byte containing having the
 * valud of two characters e.g. string "ab"
 * becomes hexidecimal integer 0xab.
 */
unsigned char DES::twoCharToHexByte(const char* twoChars)
{
	/* The byte */
	unsigned char singleByte;
	
	/* The second character */
	unsigned char secondChar;

	/* Convert the first character */
	if((singleByte = charToHex(twoChars[0])) == 'z') 
	{
		/* Invalid digit */
		return 'z';
	}
	
	/* Move the newly inserted nibble from the
	 * lower to upper nibble.
	 */
	singleByte = (singleByte << 4);
	
	/* Conver the second character */
	if((secondChar = charToHex(twoChars[1])) == 'z')
		return 'z'; 
	
	/* Insert the second value into the lower nibble */	
	singleByte |= secondChar;

	return singleByte;
}
示例#2
0
void DES(char text[], char key[])
{
	//64 bits= 8 byte
	char textHEX[64];
	char KEY[64];
	charToHex(text, textHEX);
	charToHex(key, KEY);
	iniPer(textHEX);
	round(textHEX, KEY);
}
示例#3
0
/**
 * Parse a hash colour (#rgb or #rrggbb)
 *
 * \param data    Pointer to colour string
 * \param result  Pointer to location to receive result (AARRGGBB)
 * \return CSS_OK      on success,
 *         CSS_INVALID if the input is invalid
 */
css_error css__parse_hash_colour(lwc_string *data, uint32_t *result)
{
	uint8_t r = 0, g = 0, b = 0, a = 0xff;
	size_t len = lwc_string_length(data);
	const char *input = lwc_string_data(data);

	if (len == 3 &&	isHex(input[0]) && isHex(input[1]) &&
			isHex(input[2])) {
		r = charToHex(input[0]);
		g = charToHex(input[1]);
		b = charToHex(input[2]);

		r |= (r << 4);
		g |= (g << 4);
		b |= (b << 4);
	} else if (len == 6 && isHex(input[0]) && isHex(input[1]) &&
			isHex(input[2]) && isHex(input[3]) &&
			isHex(input[4]) && isHex(input[5])) {
		r = (charToHex(input[0]) << 4);
		r |= charToHex(input[1]);
		g = (charToHex(input[2]) << 4);
		g |= charToHex(input[3]);
		b = (charToHex(input[4]) << 4);
		b |= charToHex(input[5]);
	} else
		return CSS_INVALID;

	*result = (a << 24) | (r << 16) | (g << 8) | b;

	return CSS_OK;
}
std::string decodeUrl(std::string url){
    std::string lru;
    char a,b;
    unsigned c = 0;
    for(c=0;c < url.length();c++){
        if( url[c]=='%' && ((a=url[c+1]) && (b=url[c+2])) && (std::isxdigit(a) && std::isxdigit(b)) ) {
            lru +=16*charToHex(a)+charToHex(b);
            c+=2;   // Two extra char are read
        } else {
            lru += url[c];
        }
    }
    return lru;
}
示例#5
0
文件: plMD5.cpp 项目: boq/libhsplasma
void plMD5Hash::fromHex(const char* hex) {
    HashConvert hc;

    if (strlen(hex) != 32)
        throw hsBadParamException(__FILE__, __LINE__, "Invalid hex string");
    for (size_t i=0; i<16; i++) {
        int ch1 = charToHex(hex[(2*i)    ]);
        int ch2 = charToHex(hex[(2*i) + 1]);
        if (ch1 == -1 || ch2 == -1)
            throw hsBadParamException(__FILE__, __LINE__, "Invalid hex string");
        hc.hash8[i] = ((ch1 << 4) & 0xF0) | (ch2 & 0x0F);
    }

    fHash[0] = LESWAP32(hc.hash32[0]);
    fHash[1] = LESWAP32(hc.hash32[1]);
    fHash[2] = LESWAP32(hc.hash32[2]);
    fHash[3] = LESWAP32(hc.hash32[3]);
}
示例#6
0
vector<uint8_t> Converter::generateHex(string input) {
    vector<uint8_t> payload;
    for (char c: input) {
        int item = charToHex(c);
        if (item >= 0) {
            payload.push_back(item);
        }
    }
    return payload;
}
示例#7
0
static std::string out_hex_string(const poppler::byte_array &str)
{
    std::string ret(str.size() * 2, '\0');
    const char *str_p = &str[0];
    for (unsigned int i = 0; i < str.size(); ++i, ++str_p) {
        ret[i * 2] = charToHex((*str_p & 0xf0) >> 4);
        ret[i * 2 + 1] = charToHex(*str_p & 0xf);
    }
    return ret;
}
示例#8
0
文件: xml.cpp 项目: dcdelia/mcvm
	/***************************************************************
	* Function: Parser::parseTagName()
	* Purpose : Parse the name of an XML tag
	* Initial : Maxime Chevalier-Boisvert on October 20, 2008
	****************************************************************
	Revisions and bug fixes:
	*/
	std::string Parser::parseTagName(const std::string& xmlString, size_t& charIndex, const PosVector& positions)
	{
		// If the first character is '/'
		if (xmlString[charIndex] == '/')
		{
			// Move to the next character
			++charIndex;
		}

		// If the first character is not alphanumeric
		if (!isalnum(xmlString[charIndex]))
		{
			// Throw an exception
			throw ParseError("Invalid tag name", positions[charIndex]);
		}

		// Declare a string for the tag name
		std::string tagName;

		// For each character
		for (;; ++charIndex)
		{
			// If we are past the length of the input stream
			if (charIndex > xmlString.length())
			{
				// Throw an exception
				throw ParseError("Unexpected end of stream in tag name", positions[charIndex]);
			}

			// Extract the current and next characters
			unsigned char thisChar = xmlString[charIndex];
			unsigned char nextChar = xmlString[charIndex+1];

			// If this character is not alphanumeric
			if (!isalnum(thisChar))
			{
				// Throw an exception
				throw ParseError("Non alphanumeric character in tag name (" + charToHex(thisChar) + ")", positions[charIndex]);
			}

			// Add this character to the tag name
			tagName += thisChar;

			// If the next character is a space, a slash or a tag end
			if (isspace(nextChar) || nextChar == '/' || nextChar == '>')
			{
				// This is the end of the name
				break;
			}
		}

		// Return the tag name
		return tagName;
	}
示例#9
0
/**
 * @brief QMD5::charsToHex
 * Converts a 16 sized array of chars into a 32 sized string with encoded chars
 * It's used to send to ROS the encoded MD5 password.
 * @param s the array of chars to convert. Must has 16 chars.
 * @return The hexadecimal pairs number representation of chars.
 */
QString QMD5::charsToHex(const QByteArray &s)
{
	char rtn[32 + 1];

	for( int i = 0; i < 16; ++i )
	{
		rtn[(i<<1)+1] = charToHex(s[i] & 0xF);
		rtn[i<<1] = charToHex((s[i]>>4) & 0xF);
	}
	rtn[32] = '\0';

	return QString::fromLatin1(rtn);
}
示例#10
0
 const char* hexToBase64(const char* input) {
     uint64_t length = strlen(input);
     string payload;
     int i = 0;
     while (i < length) {
         hexBase64 hb64 {0};
         uint8_t item;
         for (int j = 1; j < 7; ) {
             if (i >= length) {
                 item = 0;
             } else {
                 item = charToHex(input[i++]);
             }
             if (item >= 0) {
                 item = (uint8_t) item;
                 switch (j) {
                     case 1:
                         hb64.h24.h1 = item;
                         break;
                     case 2:
                         hb64.h24.h2 = item;
                         break;
                     case 3:
                         hb64.h24.h3 = item;
                         break;
                     case 4:
                         hb64.h24.h4 = item;
                         break;
                     case 5:
                         hb64.h24.h5 = item;
                         break;
                     case 6:
                         hb64.h24.h6 = item;
                         break;
                 }
                 j++;
             }
         }
         payload.push_back(base64_chars[hb64.b64.b1]);
         payload.push_back(base64_chars[hb64.b64.b2]);
         payload.push_back(base64_chars[hb64.b64.b3]);
         payload.push_back(base64_chars[hb64.b64.b4]);
     }
     uint baseStringLength = payload.length() - 1;
     uint padding = length % 3;
     for (int i = 0; i < padding; i++) {
         payload.replace(baseStringLength - i, 1, "=");
     }
     return payload.c_str();
 }
示例#11
0
std::string EnigmaMachine::encrypt(std::string const& text)
{
  int length(text.size()+1); // we include the trailing null character
  // The maximum cipher text length for n bytes of plane text is n + AES_BLOCK_SIZE bytes 
  int cipherTextLength = length + AES_BLOCK_SIZE;
  int finishLength = 0;
  const char* plainText(text.c_str());

/*
  std::cout << "String to encrypt: " << text << std::endl;
  std::cout << "String length: " << length << " (inc. \\0)" << std::endl;
  std::cout << "Seed " << m_seed << std::endl;
  std::cout << "Maximum cipher text length: " << cipherTextLength << std::endl;
   

  for (int i = 0;  i < length; ++i) {
      std::cout << plainText[i] << "  " 
                << charToBin(plainText[i]) << " - " 
                << charToHex(plainText[i]) 
                << std::endl;
  }
*/

  BinaryData* cipherText = new BinaryData[cipherTextLength];

  // allows reusing of m_encryptContext for multiple encryption cycles
  EVP_EncryptInit_ex(&m_encryptContext, NULL, NULL, NULL, NULL);

  // Update ciphertext, cipherTextLength is filled with the length of
  // ciphertext generated, length is the size of plaintext in bytes 
  EVP_EncryptUpdate(&m_encryptContext, cipherText, &cipherTextLength, 
     (BinaryData const*)plainText, length);

  /* update ciphertext with the final remaining bytes */
  EVP_EncryptFinal_ex(&m_encryptContext, cipherText+cipherTextLength, &finishLength);

  length = cipherTextLength + finishLength;

  // convert cipherText to hex encoded data
  // std::cout << "Actual  cipher text length: " << length << std::endl;
  std::string cipher;
  for (int i = 0;  i < length; ++i) {
      cipher += charToHex(cipherText[i]);
  }
  std::cout << cipher << std::endl << std::endl;

  delete[] cipherText;
  return  cipher;
}
示例#12
0
/*
 If the view has changed, update the contents of the 
 output console accordingly.
*/
void UsbConsole::onView(QString view)
{
  if(view == currentView) // we haven't changed
    return;
  currentView = view;
  if(!outputConsole->blockCount()) // the console is empty
    return;

  QTextCursor c = outputConsole->textCursor();
  c.movePosition(QTextCursor::Start);
  bool keepgoing = true;
  while(keepgoing)
  {
    if(view == "Characters")
      hexToChar(&c);
    else if(view == "Hex")
      charToHex(&c);
    keepgoing = c.movePosition(QTextCursor::NextBlock);
  }
}
示例#13
0
std::string EnigmaMachine::mdHash(std::string const& input)
{
   const EVP_MD* md(EVP_sha1());
   EVP_MD_CTX* mdContext(EVP_MD_CTX_create());
   EVP_DigestInit_ex(mdContext, md, NULL);

   // The input is hashed twice, with the seed used as salt 
   // for good measure.
   EVP_DigestUpdate(mdContext, input.c_str(), input.size());
   EVP_DigestUpdate(mdContext, &m_seed, sizeof(unsigned int));
   EVP_DigestUpdate(mdContext, input.c_str(), input.size());

   unsigned int mdLength;
   BinaryData mdValue[EVP_MAX_MD_SIZE];
   EVP_DigestFinal_ex(mdContext, mdValue, &mdLength);
   EVP_MD_CTX_destroy(mdContext);

   std::string hash;
   for (unsigned int i = 0; i < mdLength; ++i)  hash += charToHex(mdValue[i]);
   return hash;
}
示例#14
0
std::string
form_urlencode(const std::string& src)
{
  std::string result;
  std::string::const_iterator iter;

  for(iter = src.begin(); iter != src.end(); ++iter) {
    switch(*iter) {
    case ' ':
      result.append(1, '+');
      break;
      // alnum
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
    case 'V': case 'W': case 'X': case 'Y': case 'Z':
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
    case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
    case 'v': case 'w': case 'x': case 'y': case 'z':
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
    case '7': case '8': case '9':
      // mark
    case '-': case '_': case '.': case '!': case '~': case '*': case '\'':
    case '(': case ')':
      result.append(1, *iter);
      break;
      // escape
    default:
      result.append(1, '%');
      result.append(charToHex(*iter));
      break;
    }
  }

  return result;
}
/*!  Process byte received from debugger
 *
 * @return - !=NULL => Complete packet
 *           ==NULL => Packet not (yet) available
 */
const GdbPacket *GdbInOut::processRxByte(int byte) {
   //   LOGGING_Q;
   static GdbPacket packet1;
   static GdbPacket packet2;
   static GdbPacket *packet = &packet1;
   static unsigned char  checksum    = 0;
   static unsigned char  xmitcsum    = 0;
   static unsigned int   sequenceNum = 0;

   if (!connectionActive) {
      Logging::print("Connection not active\n");
      return NULL;
   }
   if (byte == -GDB_FATAL_ERROR) {
      Logging::print("-GDB_FATAL_ERROR\n");
      finish();
      return NULL;
   }
   if (byte < 0) {
      Logging::print("-GDB_NONFATAL_ERROR\n");
      return NULL;
   }
   switch(state) {
      case hunt: // Looking for start of packet (or Break)
         if (byte == '$') { // Start token
            state         = data;
            checksum      = 0;
            packet->size  = 0;
         }
         else if (byte == 0x03) { // Break request
            return &GdbPacket::breakToken;
         }
         break;
      case data: // Data bytes within packet
         if (byte == '}') { // Escape token
            state     = escape;
            checksum  = checksum + byte;
         }
         else if (byte == '$') { // Unexpected start token
            state          = data;
            checksum       = 0;
            packet->size   = 0;
         }
         else if (byte == '#') { // End of data token
            state    = checksum1;
         }
         else { // Regular data
            if (packet->size < GdbPacket::MAX_MESSAGE) {
               packet->buffer[packet->size++] = byte;
            }
            checksum  = checksum + byte;
         }
         break;
      case escape: // Escaped byte within data
         state    = data;
         checksum = checksum + byte;
         byte       = byte ^ 0x20;
         if (packet->size < GdbPacket::MAX_MESSAGE) {
            packet->buffer[packet->size++] = byte;
         }
         break;
      case checksum1: // 1st Checksum byte
         state    = checksum2;
         xmitcsum = charToHex(byte) << 4;
         break;
      case checksum2: // 2nd Checksum byte
         xmitcsum += charToHex(byte);
         if (checksum != xmitcsum) {
            // Invalid packet - discard and start again
            Logging::print("\nBad checksum: my checksum = %2.2X, ", checksum);
            Logging::print("sent checksum = %2.2X\n", xmitcsum);
            Logging::print(" -- Bad buffer: \"%s\"\n", packet->buffer);
            state = hunt;
         }
         else {
            // Complete packet
            packet->checkSum = checksum;
            packet->buffer[packet->size] = '\0';
            packet->sequence = ++sequenceNum;
            state = hunt;
            GdbPacket *const tPacket = packet;
            if (packet == &packet1) {
               packet = &packet2;
            }
            else {
               packet = &packet1;
            }
            return tPacket;
         }
         break;
   }
   return NULL;
}
示例#16
0
文件: ed2khash.cpp 项目: geekt/amule
/// Set Ed2k hash from a file
// returns false if aborted
bool Ed2kHash::SetED2KHashFromFile(const wxFileName& filename, MD4Hook hook)
{
  // Open file and let wxFFile destructor close the file
  // Closing it explicitly may crash on Win32 ...
  wxFFile file(filename.GetFullPath(), wxT("rbS"));
  if (! file.IsOpened())
    {
      wxLogError (_("Unable to open %s"),unicode2char(filename.GetFullPath()));
      return (false);
    }
  else
    {
      unsigned char ret[MD4_HASHLEN_BYTE];
      MD4Context hdc;

      size_t read;
      size_t partcount;
      size_t dataread;
      wxFileOffset totalread;

      char *buf = new char[BUFSIZE];

      bool goAhead = true;

#ifdef WANT_STRING_IMPLEMENTATION

      wxString tmpHash(wxEmptyString);
#else

      unsigned char* tmpCharHash = NULL;
#endif
      // Clear Ed2k Hash
      m_ed2kArrayOfHashes.Clear();

      // Processing each block
      totalread=0;
      partcount = 0;
      while (!file.Eof())
        {
          dataread = 0;
          MD4Init(&hdc);
          while (dataread < PARTSIZE && !file.Eof())
            {
              if (hook)
                {
                  goAhead = hook((int)((double)(100.0 * totalread) / file.Length()));
                }
              if (goAhead)
                {
                  if ((dataread + BUFSIZE) > PARTSIZE)
                    {
                      read = file.Read(buf, PARTSIZE - dataread);
                    }
                  else
                    {
                      read = file.Read(buf, BUFSIZE);
                    }
                  dataread += read;
                  totalread += read;
                  MD4Update(&hdc, reinterpret_cast<unsigned char const *>(buf),
                            read);
                }
              else
                {
                  return (false);
                }

            }
          MD4Final(&hdc, ret);

          // Add part-hash
          m_ed2kArrayOfHashes.Add(charToHex(reinterpret_cast<const char *>(ret),
                                            MD4_HASHLEN_BYTE));

          partcount++;

#ifdef WANT_STRING_IMPLEMENTATION
          // MD4_HASHLEN_BYTE is ABSOLUTLY needed as we dont want NULL
          // character to be interpreted as the end of the parthash string
#if wxUSE_UNICODE

          tmpHash += wxString(reinterpret_cast<const wchar_t *>(ret),MD4_HASHLEN_BYTE);
#else

          tmpHash += wxString(reinterpret_cast<const char *>(ret),MD4_HASHLEN_BYTE);
#endif
#else

          tmpCharHash = (unsigned char*)realloc(tmpCharHash,
                                                sizeof(unsigned char) * (MD4_HASHLEN_BYTE * partcount));
          memcpy ( tmpCharHash + MD4_HASHLEN_BYTE * (partcount - 1), ret, MD4_HASHLEN_BYTE );
#endif

        }

      delete [] buf;

      // hash == hash of concatenned parthashes
      if (partcount > 1)
        {
          wxString finalHash;

#ifdef WANT_STRING_IMPLEMENTATION

          finalHash=calcMd4FromString(tmpHash);
#else

          MD4Init(&hdc);
          MD4Update(&hdc, tmpCharHash, MD4_HASHLEN_BYTE * partcount);
          MD4Final(&hdc, ret);

          finalHash = charToHex(reinterpret_cast<const char *>(ret),
                                MD4_HASHLEN_BYTE);
#endif

          m_ed2kArrayOfHashes.Add(finalHash);
        }

#ifndef WANT_STRING_IMPLEMENTATION
      free(tmpCharHash);
      tmpCharHash=NULL;
#endif

      m_ed2kArrayOfHashes.Shrink();

      // Set members
      m_fileSize = file.Length();
      m_filename = filename.GetFullName();

      return true;
    }
}
示例#17
0
static int pm51_rw(uint8_t sendCmd[], int send_len, uint8_t* recvbuffer)
{
	int i, j, ret;
	uint8_t len;
	uint8_t bh,bl;
	uint8_t lsr;
	uint8_t spin;

	mutex_lock(&uart_lock);
/*	ret = mutex_trylock(&uart_lock);
	if (ret)
		return ret;
*/
	_DBG(2, "start\n");

	// Clear recvbuffer
#if 0	
	for (i=0; i<sizeof(recvbuffer); i++)
		recvbuffer[i] = 0;
#endif	

	// Clear the vuart
	spin = 1;
	do {
		inb(VUART_BASE);
		lsr = inb(VUART_LSR);
	} while((lsr & 0x1) && (spin++ != 0));

	// Enter connected state with 8051 by sending sendCmd

	// Send encoded start command
	for(i=0; i < send_len; i++)
	{
		outb(sendCmd[i], VUART_BASE);
		usleep_range(BAUDRATE_9600, BAUDRATE_9600+100);
	}

	// Decode protocol stream from 8051 FW
	// First reply will be ack then will be the version answer...

	// Wait for data ready
	spin=1;
	do {
		lsr = inb(VUART_LSR);
	} while(((lsr & 0x1) == 0) && (spin++ != 0));

	len = inb(VUART_BASE); // SYNC
	if(len != SYNC)
	{
		printk(KERN_ERR "8051 FW I/O Module does not exist\n");
		ret = -ENODEV;
		goto out;
	}
	if (sendCmd[1]==6)
	{
		ret = 0;
		goto out;
	}

	ret = -EPERM;
	// The first set of bytes is the protocol ACK so lets read bytes until
	// we get the next sync = SYNC
	spin=1;
	do {
	   len = inb(VUART_BASE);
	   usleep_range(BAUDRATE_9600, BAUDRATE_9600+100);
	} while((len != SYNC) && (spin++ != 0));

	// Check for spinout  
	if(len != SYNC)
	{
		printk(KERN_ERR "8051 Target parameter does not exist (1)\n");
		goto out;
	}

	// Now the remaining protocol with encoded version info
	// SYNC (already read above),LEN (of Encoded bytes),
	// Encoded bytes = CMD_VERSION,Len (of version data),Version data
	len = inb(VUART_BASE);
	if (len == 0)
		printk(KERN_ERR "8051 Target parameter does not exist (2)\n");
	else
		_DBG(1, "8051 Target parameter length: %d", len);

	j = 0;
	for (i=0; i < len/2; i++) {
		bh = charToHex(inb(VUART_BASE));
		usleep_range(BAUDRATE_9600, BAUDRATE_9600+100);
		bl = charToHex(inb(VUART_BASE));
		usleep_range(BAUDRATE_9600, BAUDRATE_9600+100);
		if (i==0) {
			ret=(bh << 4) | bl;
		} else if (i==1) {
			if (ret ==CMD_PWM_FAN) {
				recvbuffer[j++] = (bh << 4) | bl;
				_DBG(1, "%c %d", recvbuffer[j-1], recvbuffer[j-1]);
			}
		//First four bytes are the encoded CMD enum and the length which is redundant, which is redundant.
		} else {
			recvbuffer[j++] = (bh << 4) | bl;
			_DBG(1, "%c %d", recvbuffer[j-1], recvbuffer[j-1]);
		}	
	}

	_DBG(1, "\n");

	// Clear the vuart
	spin = 1;
	do {
		inb(VUART_BASE);
		lsr = inb(VUART_LSR);
	} while((lsr & 0x1) && (spin++ != 0));

	ret = 0;
out:
	_DBG(2, "end\n");
	mutex_unlock(&uart_lock);
	return ret;
}
示例#18
0
/// parses input stream
bool LVRtfParser::Parse()
{
    //m_conv_table = GetCharsetByte2UnicodeTable( L"cp1251" );

    bool errorFlag = false;
    m_callback->OnStart(this);

    // make fb2 document structure
    m_callback->OnTagOpen( NULL, L"?xml" );
    m_callback->OnAttribute( NULL, L"version", L"1.0" );
    m_callback->OnAttribute( NULL, L"encoding", L"utf-8" );
    //m_callback->OnEncoding( GetEncodingName().c_str(), GetCharsetTable( ) );
    m_callback->OnTagBody();
    m_callback->OnTagClose( NULL, L"?xml" );
    m_callback->OnTagOpenNoAttr( NULL, L"FictionBook" );
      // DESCRIPTION
      m_callback->OnTagOpenNoAttr( NULL, L"description" );
        m_callback->OnTagOpenNoAttr( NULL, L"title-info" );
          //
            lString16 bookTitle = LVExtractFilenameWithoutExtension( getFileName() ); //m_stream->GetName();
            m_callback->OnTagOpenNoAttr( NULL, L"book-title" );
                if ( !bookTitle.empty() )
                    m_callback->OnText( bookTitle.c_str(), bookTitle.length(), 0 );
          //queue.DetectBookDescription( m_callback );
        m_callback->OnTagOpenNoAttr( NULL, L"title-info" );
      m_callback->OnTagClose( NULL, L"description" );
      // BODY
      m_callback->OnTagOpenNoAttr( NULL, L"body" );
        //m_callback->OnTagOpen( NULL, L"section" );
          // process text
          //queue.DoTextImport( m_callback );
        //m_callback->OnTagClose( NULL, L"section" );

    txtbuf = new lChar16[ MAX_TXT_SIZE+1 ];
    txtpos = 0;
    txtfstart = 0;
    char cwname[33];
    while ( !Eof() && !errorFlag && !m_stopped ) {
        // load next portion of data if necessary
        if ( m_buf_len - m_buf_pos < MIN_BUF_DATA_SIZE ) {
            if ( !FillBuffer( MIN_BUF_DATA_SIZE*2 ) ) {
                errorFlag = true;
                break;
            }
        }
        int len = (int)m_buf_len - (int)m_buf_pos;
        // check end of file
        if ( len <=0 )
            break; //EOF
        const lUInt8 * p = m_buf + m_buf_pos;
        lUInt8 ch = *p++;
        if ( ch=='{' ) {
            OnBraceOpen();
            m_buf_pos++;
            continue;
        } else if ( ch=='}' ) {
            OnBraceClose();
            m_buf_pos++;
            continue;
        }
        lUInt8 ch2 = *p;
        if ( ch=='\\' && *p!='\'' ) {
            // control
            bool asteriskFlag = false;
            if ( ch2=='*' ) {
                ch = *(++p);
                ch2 = *(++p);
                asteriskFlag = true;
            }
            if ( (ch2>='A' && ch2<='Z') || (ch2>='a' && ch2<='z') ) {
                // control word
                int cwi = 0;
                do {
                    cwname[cwi++] = ch2;
                    ch2 = *++p;
                } while ( ( (ch2>='A' && ch2<='Z') || (ch2>='a' && ch2<='z') ) && cwi<32 );
                cwname[cwi] = 0;
                int param = PARAM_VALUE_NONE;
                if ( ch2==' ' ) {
                    p++;
                } else {
                    if ( ch2 == '-' ) {
                        p++;
                        param = 0;
                        for ( ;; ) {
                            ch2 = *++p;
                            if ( ch2<'0' || ch2>'9' )
                                break;
                            param = param * 10 + (ch2-'0');
                        }
                        param = -param;
                    } else if ( ch2>='0' && ch2<='9' ) {
                        param = 0;
                        while ( ch2>='0' && ch2<='9' ) {
                            param = param * 10 + (ch2-'0');
                            ch2 = *++p;
                        }
                    }
                    if ( *p == ' ' )
                        p++;
                }
                // \uN -- unicode character
                if ( cwi==1 && cwname[0]=='u' ) {
                    AddChar( (lChar16) (param & 0xFFFF) );
//                    if ( m_stack.getInt( pi_skip_ch_count )==0 )
//                        m_stack.set( pi_skip_ch_count, 1 );
                } else {
                    // usual control word
                    OnControlWord( cwname, param, asteriskFlag );
                }
            } else {
                // control char
                cwname[0] = ch2;
                cwname[1] = 0;
                p++;
                OnControlWord( cwname, PARAM_VALUE_NONE, asteriskFlag );
            }
            m_buf_pos += p - (m_buf + m_buf_pos);
        } else {
            //lChar16 txtch = 0;
            if ( ch=='\\' ) {
                p++;
                int digit1 = charToHex( p[0] );
                int digit2 = charToHex( p[1] );
                p+=2;
                if ( digit1>=0 && digit2>=0 ) {
                    AddChar8( (lChar8)((digit1 << 4) | digit2) );
                } else {
                    AddChar('\\');
                    AddChar('\'');
                    AddChar8(digit1);
                    AddChar8(digit2);
                    p+=2;
                }
            } else {
                if ( ch>=' ' ) {

                    AddChar8( ch );
                } else {
                    // wrong char
                }
            }
            //=======================================================
            //=======================================================
            m_buf_pos += p - (m_buf + m_buf_pos);
        }
    }
    m_callback->OnStop();
    delete[] txtbuf;
    txtbuf = NULL;

    CommitText();
    m_stack.getDestination()->OnAction(LVRtfDestination::RA_SECTION);

      m_callback->OnTagClose( NULL, L"body" );
    m_callback->OnTagClose( NULL, L"FictionBook" );

    return !errorFlag;
}