Пример #1
0
/* Desc: Find the location of a node
*  Input: node
*  Output: String location of node
 */
CharString FileSystem::getStringFromNode(FileStructureNode* location) {
    // place a string before the current string.
    CharString cstring = CharString();

    FileStructureNode* current = location;

    // loop through and append "/" to all the names
    while(current != 0x0 && current != Root) {
        cstring.concatb(current->name);
        cstring.concatb("/",1);

        current = current->Parent;
    }
    //cstring.concatb("/",1);
    return cstring;
}
Пример #2
0
Variant _Marshalls::base64_to_variant(const String& p_str) {

    int strlen = p_str.length();
    CharString cstr = p_str.ascii();

    DVector<uint8_t> buf;
    buf.resize(strlen / 4 * 3 + 1);
    DVector<uint8_t>::Write w = buf.write();

    int len = base64_decode((char*)(&w[0]), (char*)cstr.get_data(), strlen);

    Variant v;
    Error err = decode_variant(v, &w[0], len);
    ERR_FAIL_COND_V( err!=OK, Variant() );

    return v;
};
Пример #3
0
void Logger::processLog(CharString data){
    if(console){
        cout << data.get() << endl;
        cout.flush();
    }
    
    // push data to file
}
Пример #4
0
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CProcessor::ProcessStopApply(TradeRecord *trade,
                                 const ConGroup *group, const int isTP)
{
    char *groupStr = new char[50];
    strcpy(groupStr, group->group);
    if (CheckGroup(m_groups, groupStr) == FALSE)
    {
        delete []groupStr;
        return FALSE;
    }
    delete []groupStr;

    double price = 0;
    // получим текущие цены для группы и установки символа
    double    prices[2] = { 0, 0 };
    int orderSide = trade->cmd == OP_BUY ? 1 : 0;
    if (ExtServer->HistoryPricesGroup(trade->symbol, group, prices) == RET_OK)
    {
        int orderSide = trade->cmd == OP_BUY ? 0 : 1; // меняется от знака сделки
        price = prices[orderSide];
    }

    CharString strMsg;
    strMsg.Printf(FALSE, "%s (%s at %g) is applying to order %d",
                  isTP ? "TP" : "SL",
                  orderSide == 1 ? "BUY" : "SELL",
                  price,
                  trade->order);
    ExtServer->LogsOut(CmdOK, PROGRAM_TITLE, strMsg.ToArray());

    SLTPOrderRequest req = { trade->order, price };
    m_orderRequests.Enqueue(&req);

    // отправить запрос на сервер
    int requestId = m_nextStopRequestId++;
    strMsg.Printf(FALSE, "requestId=%d;type=%s;price=%g;login=%d;symbol=%s;volume=%d;",
                  trade->order,
                  isTP ? "TP" : "SL",
                  price,
                  trade->login,
                  trade->symbol,
                  trade->volume);
    m_sender->SendTo(&strMsg, m_sendHost, m_sendPort);

    return TRUE;
}
Пример #5
0
 void transform(const UnicodeString &word, CharString &buf, UErrorCode &errorCode) {
     UChar32 c = 0;
     int32_t len = word.length();
     for (int32_t i = 0; i < len; i += U16_LENGTH(c)) {
         c = word.char32At(i);
         buf.append(transform(c, errorCode), errorCode);
     }
 }
Пример #6
0
	//find W(word) in S(sentence)
	//return the index of the first appearance
	//implementing KMP algorithm
	int CharString::indexOf(CharString W, int start) const{
		if(W.length() == 0)
			return NOT_FOUND;
		if(W.length() == 1)
			return indexOf(W[0], start);

		//first, make the table
		int* T = new int[W.length()];
		int pos=2, cnd=0;
		T[0] = -1;
		T[1] = 0;

		while(pos < W.length()){
			if(W[pos-1] == W[cnd]){
				cnd = cnd + 1;
				T[pos] = cnd;
				pos = pos + 1;
			}else if(cnd > 0){
				cnd = T[cnd];
			}else{
				T[pos] = 0;
				pos = pos + 1;
			}
		}


		//now let's do KMP 
		int m=start, i=0;
		while((m + i) < length()){
			if(W[i] == operator[](m+i)){
				if(i == W.length() - 1)
					return m;
				i = i + 1;
			}else{
				if(T[i] > -1){
					m = m + i - T[i];
					i = T[i];
				}else{
					i = 0;
					m = m + 1;
				}
			}
		}
		return NOT_FOUND;
	}
Пример #7
0
/**
 *  Return a string form of this number.
 *     Format is as defined by the decNumber library, for interchange of
 *     decimal numbers.
 */
void DigitList::getDecimal(CharString &str, UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }

    // A decimal number in string form can, worst case, be 14 characters longer
    //  than the number of digits.  So says the decNumber library doc.
    int32_t maxLength = fDecNumber->digits + 14;
    int32_t capacity = 0;
    char *buffer = str.clear().getAppendBuffer(maxLength, 0, capacity, status);
    if (U_FAILURE(status)) {
        return;    // Memory allocation error on growing the string.
    }
    U_ASSERT(capacity >= maxLength);
    uprv_decNumberToString(this->fDecNumber, buffer);
    U_ASSERT((int32_t)uprv_strlen(buffer) <= maxLength);
    str.append(buffer, -1, status);
}
Пример #8
0
void RichTextEditor::_file_selected(const String& p_path) {

	CharString cs;
	FileAccess *fa = FileAccess::open(p_path,FileAccess::READ);
	if (!fa) {
		ERR_FAIL();
	}

	while(!fa->eof_reached())
		cs.push_back(fa->get_8());
	cs.push_back(0);
	memdelete(fa);

	String bbcode;
	bbcode.parse_utf8(&cs[0]);
	node->parse_bbcode(bbcode);

}
Пример #9
0
void
NamesPropsBuilder::setProps(const UniProps &props, const UnicodeSet &newValues,
                            UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    if(!newValues.contains(UCHAR_NAME) && !newValues.contains(PPUCD_NAME_ALIAS)) {
        return;
    }

    U_ASSERT(props.start==props.end);

    const char *names[4]={ NULL, NULL, NULL, NULL };
    int16_t lengths[4]={ 0, 0, 0, 0 };

    /* get the character name */
    if(props.name!=NULL) {
        names[0]=props.name;
        lengths[0]=(int16_t)uprv_strlen(props.name);
        parseName(names[0], lengths[0]);
    }

    CharString buffer;
    if(props.nameAlias!=NULL) {
        /*
         * Only use "correction" aliases for now, from Unicode 6.1 NameAliases.txt with 3 fields per line.
         * TODO: Work on ticket #8963 to deal with multiple type:alias pairs per character.
         */
        const char *corr=uprv_strstr(props.nameAlias, "correction=");
        if(corr!=NULL) {
            corr+=11;  // skip "correction="
            const char *limit=uprv_strchr(corr, ',');
            if(limit!=NULL) {
                buffer.append(corr, limit-corr, errorCode);
                names[3]=buffer.data();
                lengths[3]=(int16_t)(limit-corr);
            } else {
                names[3]=corr;
                lengths[3]=(int16_t)uprv_strlen(corr);
            }
            parseName(names[3], lengths[3]);
        }
    }

    addLine(props.start, names, lengths, LENGTHOF(names));
}
Пример #10
0
void
CurrencyAffixInfo::set(
        const char *locale,
        const PluralRules *rules,
        const UChar *currency,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return;
    }
    fIsDefault = FALSE;
    if (currency == NULL) {
        fSymbol.setTo(gDefaultSymbols, 1);
        fISO.setTo(gDefaultSymbols, 2);
        fLong.remove();
        fLong.append(gDefaultSymbols, 3);
        fIsDefault = TRUE;
        return;
    }
    int32_t len;
    UBool unusedIsChoice;
    const UChar *symbol = ucurr_getName(
            currency, locale, UCURR_SYMBOL_NAME, &unusedIsChoice,
            &len, &status);
    if (U_FAILURE(status)) {
        return;
    }
    fSymbol.setTo(symbol, len);
    fISO.setTo(currency, u_strlen(currency));
    fLong.remove();
    StringEnumeration* keywords = rules->getKeywords(status);
    if (U_FAILURE(status)) {
        return;
    }
    const UnicodeString* pluralCount;
    while ((pluralCount = keywords->snext(status)) != NULL) {
        CharString pCount;
        pCount.appendInvariantChars(*pluralCount, status);
        const UChar *pluralName = ucurr_getPluralName(
            currency, locale, &unusedIsChoice, pCount.data(),
            &len, &status);
        fLong.setVariant(pCount.data(), UnicodeString(pluralName, len), status);
    }
    delete keywords;
}
Пример #11
0
String FileAccess::get_token() const {

	CharString token;

	CharType c = get_8();

	while (!eof_reached()) {

		if (c <= ' ') {
			if (token.length())
				break;
		} else {
			token += c;
		}
		c = get_8();
	}

	return String::utf8(token.get_data());
}
Пример #12
0
// figure out what mods have good dependencies
bool APIMod::compareModDependencies(LinkedList<APIMod*> othermods){
    LinkedListIterator<CharString> depstrs = dependencyversions.getIterator();
    
    while(depstrs.hasNext()){
        CharString depstr = depstrs.next();
        if(depstr.contains(":")){
            LinkedListIterator<APIMod*> modit = othermods.getIterator();
            while(modit.hasNext()){
                APIMod *mod = modit.next();
                // compare direct
                if(! version.compareVersion(mod->version)){
                    // not the same or and older version
                    return false;
                }
            }
            
        } // else invalid!
    }
}
Пример #13
0
U_DRAFT const char * U_EXPORT2
ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
  if(U_FAILURE(*status)) {
    return "";
  }
  Formattable *obj = Formattable::fromUFormattable(fmt);
  CharString *charString = obj->internalGetCharString(*status);
  if(U_FAILURE(*status)) {
    return "";
  }
  if(charString == NULL) {
    *status = U_MEMORY_ALLOCATION_ERROR;
    return "";
  } else {
    if(len!=NULL) {
      *len = charString->length();
    }
    return charString->data();
  }
}
Пример #14
0
String FileAccess::get_token() const {

	CharString token;

	CharType c = get_8();

	while (!eof_reached()) {

		if (c <= ' ') {
			if (!token.empty())
				break;
		} else {
			token.push_back(c);
		}
		c = get_8();
	}

	token.push_back(0);
	return String::utf8(token.get_data());
}
Пример #15
0
	void convert(DipData &dipData, VariablePtr DPEValue, const CharString & tagName) const{
		TextVar * val = (TextVar *)DPEValue;
		if (!val){
			throw BadTypeConversionException(BadTypeConversionException::BADTYPE);
		}
		if (tagName.len() == 0){
			dipData.insert((char *)val->getValue());
		} else {
			dipData.insert((char *)val->getValue(), tagName); 
		}
	}
Пример #16
0
void
PreparsedUCD::parseScriptExtensions(const char *s, UnicodeSet &scx, UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return; }
    scx.clear();
    CharString scString;
    for(;;) {
        const char *scs;
        const char *scLimit=strchr(s, ' ');
        if(scLimit!=NULL) {
            scs=scString.clear().append(s, (int32_t)(scLimit-s), errorCode).data();
            if(U_FAILURE(errorCode)) { return; }
        } else {
            scs=s;
        }
        int32_t script=pnames->getPropertyValueEnum(UCHAR_SCRIPT, scs);
        if(script==UCHAR_INVALID_CODE) {
            fprintf(stderr,
                    "error in preparsed UCD: '%s' is not a valid script code on line %ld\n",
                    scs, (long)lineNumber);
            errorCode=U_PARSE_ERROR;
            return;
        } else if(scx.contains(script)) {
            fprintf(stderr,
                    "error in preparsed UCD: scx has duplicate '%s' codes on line %ld\n",
                    scs, (long)lineNumber);
            errorCode=U_PARSE_ERROR;
            return;
        } else {
            scx.add(script);
        }
        if(scLimit!=NULL) {
            s=scLimit+1;
        } else {
            break;
        }
    }
    if(scx.isEmpty()) {
        fprintf(stderr, "error in preparsed UCD: empty scx= on line %ld\n", (long)lineNumber);
        errorCode=U_PARSE_ERROR;
    }
}
Пример #17
0
// if ASYNC, start thread
Logger::Logger(CharString logfileloc, CharString prefix, bool async, bool console, bool clearfile){
    this->logfileloc = logfileloc;
    this->prefix = prefix;
    this->async = async;
    this->console = console;
    this->ending = false;
    
    //cout << "Logger 1" << endl;
    // open file
    if(clearfile) file.open (logfileloc.get(), ios::out | ios::app);
    else file.open (logfileloc.get(), ios::out | ios::app | ios::trunc);
    file.seekp(0, ios::end);
    
    //cout << "Logger 2" << endl;
    
    if(async){
        asyncthread = std::thread(loggerThread, this);
        cout << "Logger 3thrstart" << endl;
    }
    //cout << "Logger 3" << endl;
}
Пример #18
0
void Logger::Log(CharString data){
    // combine data with prefix, timestamp.
    data.concatb(prefix);
    
    // async
    if(async){
        // save for the thread
        //asyncLog.push(data);
    }else{
        processLog(data);
    }
}
bool Dictionary :: LookupDta(CharString Template)//判断词库中是否存在Template
{
	//Template长度不合法,或者长度是奇数,肯定不是词库中都是有两个字节的汉字构成的词。直接返回false
	if(Template.Size > MaxLength || Template.Size <= 1 || Template.Size/2 == 1) return false;
	//找到数组中对应长度的节点
	EntryHead *q = &head[Template.Size/2];
	Entry *p;
	while(q != NULL && q->character != Template[0]) q = q->nextHead;
	//while循环找到与Template首个字节相同的链表表头
	if(q == NULL) return false;//如果没有相同表头,返回false
	else
	{
		//然后对相同表头的链表进行遍历,判断Template是否在词库中。
		if(Template.CharLineCmp(q->str0))
			return true;
		p = q->next;
		while(p != NULL && !Template.CharLineCmp(p->str0)) p = p->next;
		if(p == NULL) return false;
		return true;
	}
}
Пример #20
0
static void _fix_files(Vector<uint8_t>& html,uint64_t p_data_size) {


	String str;
	String strnew;
	str.parse_utf8((const char*)html.ptr(),html.size());
	Vector<String> lines=str.split("\n");
	for(int i=0;i<lines.size();i++) {
		if (lines[i].find("$DPLEN")!=-1) {
			strnew+=lines[i].replace("$DPLEN",itos(p_data_size));
		} else {
			strnew+=lines[i]+"\n";
		}
	}

	CharString cs = strnew.utf8();
	html.resize(cs.size());
	for(int i=9;i<cs.size();i++) {
		html[i]=cs[i];
	}
}
Пример #21
0
ENumberFormatTestTupleField
NumberFormatTestTuple::getFieldByName(
        const UnicodeString &name) {
    CharString buffer;
    UErrorCode status = U_ZERO_ERROR;
    buffer.appendInvariantChars(name, status);
    if (U_FAILURE(status)) {
        return kNumberFormatTestTupleFieldCount;
    }
    int32_t result = -1;
    for (int32_t i = 0; i < UPRV_LENGTHOF(gFieldData); ++i) {
        if (uprv_strcmp(gFieldData[i].name, buffer.data()) == 0) {
            result = i;
            break;
        }
    }
    if (result == -1) {
        return kNumberFormatTestTupleFieldCount;
    }
    return (ENumberFormatTestTupleField) result;
}
Пример #22
0
static int32_t toEnum(
        const Numberformattesttuple_EnumConversion *table,
        int32_t tableLength,
        const UnicodeString &str,
        UErrorCode &status) {
    if (U_FAILURE(status)) {
        return 0;
    }
    CharString cstr;
    cstr.appendInvariantChars(str, status);
    if (U_FAILURE(status)) {
        return 0;
    }
    for (int32_t i = 0; i < tableLength; ++i) {
        if (uprv_strcmp(cstr.data(), table[i].str) == 0) {
            return table[i].value;
        }
    }
    status = U_ILLEGAL_ARGUMENT_ERROR;
    return 0;
}
Пример #23
0
void SockClient::readhandler(){
    int n;
    const int buflen = bufferSize;
    char buffer[buflen];
    CharString writeto;
    
    Logger::GLOBAL.log("[SockClient]  reading thread started");
    
    while(alive){
        
        n = read(sockd, buffer, buflen);
        if (n < 0){
            std::this_thread::sleep_for(std::chrono::milliseconds(5));
            continue;
        }else if(n==0){
            Logger::GLOBAL.log("[SockClient] disconnected from server");
            if(disconnected != 0x0) disconnected(server, this);
            alive = false;
            return;
        }
        
        // post-clear extra data in packet... (Prevents extra cpu usage, clearer data stream)
        for(int i=n-1;i<buflen;i++) buffer[i] = 0;

        if(_clientHandler != 0x0 && n > 1) {
            //CharString d = (server->decryptor!=0x0) ? server->decryptor(CharString(buffer,n)) : CharString(buffer,n); // decrypt
            CharString d = CharString(buffer,n); // decrypt
            _clientHandler(d, writeto, this, exVAL);

            if(writeto.getSize() > 0){
                // segment packet if it is too large.
                sendc(writeto); // encryption in-client
            }
        }
    }
    
    Logger::GLOBAL.log("[SockClient] reading thread ended");
    alive = false;
}
Пример #24
0
void CdipPublicationManager::extractStringsFromCompoundString(CharString &compoundString, std::vector<std::string> & strings){
	unsigned int startOfStringInd = 0;
	unsigned int endOfStringInd = 0;
	std::string localCopy = (const char *)compoundString;
	
	char delimiter;

	//Check which delimiter is used, well at least present in the strin provided, then run the string processing.
	if (-1 != compoundString.indexOf(CdipClientManager::pubNameDelimiter[0])) {
		//Use delimiter 0
		delimiter = CdipClientManager::pubNameDelimiter[0][0];
	} else if (-1 != compoundString.indexOf(CdipClientManager::pubNameDelimiter[1])){
		//Use delimiter 1
		delimiter = CdipClientManager::pubNameDelimiter[1][0];
	} else if (-1 != compoundString.indexOf(CdipClientManager::pubNameDelimiter[0])
		 && -1 != compoundString.indexOf(CdipClientManager::pubNameDelimiter[1])
		){
		//Both delimiters present, this is a problem to report.
		PVSSERROR("Configuration string delimiters "<<CdipClientManager::pubNameDelimiter[0]<<" and "<<CdipClientManager::pubNameDelimiter[1]<<" are both present for Publications, take first one.");
		delimiter = CdipClientManager::pubNameDelimiter[0][0];
	} else {
		//No delimiter found, this is a problem to report.
		PVSSERROR("None of the configuration string delimiters "<<CdipClientManager::pubNameDelimiter[0]<<" and "<<CdipClientManager::pubNameDelimiter[1]<<" were found for Publications.");
		return;
	}

	while(endOfStringInd < localCopy.size()){
		if ((localCopy[endOfStringInd] == delimiter) || (endOfStringInd == (localCopy.size()-1))){
			int lenOfString = (endOfStringInd - startOfStringInd) + 1;
			if (localCopy[endOfStringInd] == delimiter){
				lenOfString--;
			}
			std::string str = localCopy.substr(startOfStringInd, lenOfString);
			strings.push_back(str);
			startOfStringInd = endOfStringInd+1;
		}
		endOfStringInd++;
	}
}
Пример #25
0
static void store_file_buffer(FileAccess*f,const String& p_path,const Vector<uint8_t>& p_data) {


    String pre = "Module['FS_createDataFile']('/', '"+p_path.replace("res://","")+"',[";
    CharString cs = pre.utf8();
    f->store_buffer((const uint8_t*)cs.ptr(),cs.length());
    for(int i=0; i<p_data.size(); i++) {


        uint8_t c=',';
        if (i>0)
            f->store_buffer(&c,1);

        uint8_t str[4];
        uint8_t d = p_data[i];
        if (d<10) {
            str[0]='0'+d;
            str[1]=0;
            f->store_buffer(str,1);
        } else if (d<100) {

            str[0]='0'+d/10;
            str[1]='0'+d%10;
            str[2]=0;
            f->store_buffer(str,2);

        } else {
            str[0]='0'+d/100;
            str[1]='0'+(d/10)%10;
            str[2]='0'+d%10;
            str[3]=0;
            f->store_buffer(str,3);
        }
    }
    String post = "],true,true);\n";
    cs = post.utf8();
    f->store_buffer((const uint8_t*)cs.ptr(),cs.length());
}
Пример #26
0
void TextMission::onUpdate( float t )
{
	WindowText::onUpdate( t );

	if ( visible() )
	{
		if ( activeTime() > UPDATE_MISSION_TEXT )
		{
			GameDocument * pDoc = WidgetCast<GameDocument>( document() );
			ASSERT( pDoc );
			NounShip * pShip = pDoc->ship();
			if (! pShip )
				return;

			static char * ORDER_DESC[] =
			{
				"NO ORDER %s",								// NOORDER
				"Engage %s and destroy.",					// ATTACK
				"Defend %s from attack by enemy ships.",	// DEFEND
				"Capture %s.",								// CAPTURE
				"Proceed to %s.",							// MOVE
				"Reload and repair %s.",					// RELOAD
				"Attach beacon to %s.",						// BEACON
				"Hold current position %s.",				// HOLD
				"Trade %s",									// TRADE
				"Recon enemy positions at %s.",				// RECON
				"Build structures on %s.",					// BUILD
				"Fallback and repair at %s."				// FALLBACK
			};

			CharString sText;
			sText.format( ORDER_DESC[ pShip->order() ], pShip->orderTarget() ? pShip->orderTarget()->name() : "" );

			setText( sText );
			setActiveTime( 0 );
		}
	}
}
Пример #27
0
  bool File::open (FileAccess::Enum access, FileCondition::Enum condition)
  {
    DWORD winAccess = 0;
    DWORD winCondition = 0;

    //Setup access permissions
    switch (access) {
    case FileAccess::Read:
      winAccess = GENERIC_READ;
      break;
    case FileAccess::Write:    
      winAccess = GENERIC_WRITE;
      break;
    case FileAccess::ReadWrite:
      winAccess = GENERIC_READ | GENERIC_WRITE;
      break;
    }

    //Setup creation disposition
    if (condition & FileCondition::MustNotExist) {
      winCondition = CREATE_NEW;
    }
    else if (condition & FileCondition::MustExist) {
      if (condition & FileCondition::Truncate)
        winCondition = TRUNCATE_EXISTING;
      else winCondition = OPEN_EXISTING;
    }
    else {
      if (condition & FileCondition::Truncate)
        winCondition = CREATE_ALWAYS;
      else winCondition = OPEN_ALWAYS;
    }

    //Create the file
    CharString longpath = "\\\\?\\" + getPathName();
    handle = CreateFile( longpath.buffer(), winAccess, 0, NULL, winCondition, 0, NULL );
    return (handle != INVALID_HANDLE_VALUE);
  }
Пример #28
0
// Handle basic client stuff
void ClientHandler_(SockClient* tclient) {
    // Talk with the client, pre-load into a buffer
    int n;
    char buffer[BUFFER_SIZEX];

    while(tclient->alive) {
#if __linux__ || __unix__


        n = read(tclient->sockd, buffer, BUFFER_SIZEX);
        if (n < 0) error("ERROR reading from socket");

        CharString* writeto = new CharString(); // writeto is a string that we write to, used by the

        if(tclient->_clientHandler != 0x0) {
            tclient->_clientHandler(new CharString(buffer,BUFFER_SIZEX), writeto);

            n = write(tclient->sockd, writeto->get(), writeto->getSize());
            if (n < 0) error("ERROR writing to socket");
        }
#endif // __linux__
    }
}
Пример #29
0
	void convert(DipData &dipData, VariablePtr DPEValue, const CharString & tagName) const{
		CharVar * val = (CharVar *)DPEValue;
		if (!val){
			throw BadTypeConversionException(BadTypeConversionException::BADTYPE);
		}

		char stringifiedChar[2]={0,0};
		stringifiedChar[0] = val->getValue();
		if (tagName.len() == 0){
			dipData.insert(stringifiedChar);
		} else {
			dipData.insert(stringifiedChar, tagName); 
		}
	}
Пример #30
0
static UBool thaiWordToBytes(const UChar *s, int32_t length,
                             CharString &str, UErrorCode &errorCode) {
    for(int32_t i=0; i<length; ++i) {
        UChar c=s[i];
        int32_t b=thaiCharToByte(c);
        if(b>=0) {
            str.append((char)b, errorCode);
        } else {
            fprintf(stderr, "thaiWordToBytes(): unable to encode U+%04X as a byte\n", c);
            return FALSE;
        }
    }
    return TRUE;
}