Beispiel #1
0
void splitFile(char *source, int linesPerFile, char *outBaseName,
	char *head, char *tail)
/* splitFile - Split up a file. */
{
char outName[512];
int fileIx, i;
struct lineFile *lf = lineFileOpen(source, FALSE);
FILE *f = NULL;
int lineSize;
char *line;
boolean done = FALSE;

for (fileIx=1; ; ++fileIx)
    {
    sprintf(outName, "%s%02d", outBaseName, fileIx);
    f = mustOpen(outName, "w");
    appendFile(head, f);
    for (i=0; i<linesPerFile; ++i)
        {
	if (!lineFileNext(lf, &line, &lineSize))
	    {
	    done = TRUE;
	    break;
	    }
	mustWrite(f, line, lineSize);
	}
    appendFile(tail, f);
    printf("wrote %d lines to %s\n", i, outName);
    carefulClose(&f);
    if (done)
        break;
    }
}
void writeToFile(std::vector<std::string> *gcode)
{
  std::cout << "Write to file \n";
  std::ofstream output;
  output.open ("custom_pyramid.gcode");

  appendFile(&output, "start_gcode.txt");

  for (std::vector<std::string>::iterator it = gcode->begin() ; it != gcode->end(); ++it)
    output << *it;

  appendFile(&output, "end_gcode.txt");

  output.close();
}
Beispiel #3
0
void FormData::appendItem(const BlobItem* item, bool shouldGenerateFile)
{
    const DataBlobItem* dataItem = item->toDataBlobItem();
    if (dataItem) {
        appendData(dataItem->data(), static_cast<size_t>(dataItem->size()));
        return;
    }

    const FileBlobItem* fileItem = item->toFileBlobItem();
    ASSERT(fileItem);
    if (fileItem->path().isEmpty()) {
        // If the path is empty do not add the item.
        return;
    }

#if ENABLE(BLOB_SLICE)
    const FileRangeBlobItem* fileRangeItem = item->toFileRangeBlobItem();
    if (fileRangeItem) {
        appendFileRange(fileItem->path(), fileRangeItem->start(), fileRangeItem->size(), fileRangeItem->snapshotModificationTime(), shouldGenerateFile);
        return;
    }
#endif

    appendFile(fileItem->path(), shouldGenerateFile);
}
Beispiel #4
0
void FilePath::appendPart(OovStringRef const pathPart, eFilePathTypes fpt)
{
    if(fpt == FP_Dir)
        appendDir(pathPart);
    else
        appendFile(pathPart);
}
Beispiel #5
0
void FilePath::getAbsolutePath(OovStringRef const path, eFilePathTypes fpt)
{
    if(FilePathIsAbsolutePath(path))
    {
        if(fpt == FP_Dir)
            appendDir(path);
        else
            appendFile(path);
    }
    else
    {
        getWorkingDirectory();
        FilePath newPath(path, fpt);
        int count = newPath.discardLeadingRelSegments();
        size_t pos = getPosEndDir();
        for(int i=0; i<count; i++)
        {
            pos = getPosLeftPathSep(pos, RP_RetPosNatural);
        }
        appendPathAtPos(newPath, pos);
    }
    normalizePathSeps(pathStdStr());
    if(fpt == FP_Dir)
    {
        if(!FilePathIsEndPathSep(pathStdStr()))
            pathStdStr().append("/");
    }
}
	QDebug DailyRollingFileAppender::debug(QDebug &rDebug) const
	{
	    QString layout_name;
	    if (layout())
	        layout_name = layout()->name();
	    QString codec_name;
	    if (encoding())
	        codec_name = QLatin1String(encoding()->name());
	    
	    rDebug.nospace() << "DailyRollingFileAppender(" 
	        << "name:" << name() << " "
	        << "activedatepattern:" << mActiveDatePattern << " "
	        << "appendfile:" << appendFile() << " " 
	        << "bufferedio:" << bufferedIo() << " "
	        << "datepattern:" << datePattern() << " "
	        << "encoding:" << codec_name << " "
	        << "frequency:" << frequencyToString() << " "
            << "file:" << fileName() << " "
            << "filepath:" << filePath() << " "
            << "suffix:" << suffix() << " "
            << "fullFileName:" << fullFileName() << " "
	        << "filter:" << firstFilter() << " "        
	        << "immediateflush:" << immediateFlush() << " "
	        << "isactive:" << isActive() << " "
	        << "isclosed:" << isClosed() << " "
	        << "layout:" << layout_name << " "
	        << "referencecount:" << referenceCount() << " "
	        << "rollovertime:" << mRollOverTime
	        << "threshold:" << threshold().toString()
	        << "writer:" << writer()
	        << ")";
	    return rDebug.space();    
	}
Beispiel #7
0
	QDebug RollingFileAppender::debug(QDebug &rDebug) const
	{
	    QString layout_name;
	    if (layout())
	        layout_name = layout()->name();
	    QString codec_name;
	    if (encoding())
	        codec_name = QLatin1String(encoding()->name());
	    
	    rDebug.nospace() << "RollingFileAppender(" 
	        << "name:" << name() << " "
	        << "appendfile:" << appendFile() << " "
	        << "bufferedio:" << bufferedIo() << " "
	        << "encoding:" << codec_name << " "
	        << "file:" << file() << " "
	        << "filter:" << firstFilter() << " "
	        << "immediateflush:" << immediateFlush() << " "
	        << "isactive:" << isActive() << " "
	        << "isclosed:" << isClosed() << " "
	        << "layout:" << layout_name << " "
	        << "maxbackupindex:" << maxBackupIndex() << " "
	        << "maximumfilesize:" << maximumFileSize() << " "
	        << "referencecount:" << referenceCount() << " "
	        << "threshold:" << threshold().toString() << " "
	        << "writer:" << writer()
	        << ")";
	    return rDebug.space();    
	}
Beispiel #8
0
/* prepare a cursor; return the ID number of that cursor */
static int
prepareCursor(const char *stmt, bool scrollflag)
{
    struct OCURS *o = findNewCursor();
    stmt = lineFormatStack(stmt, 0, &sqlargs);
    va_end(sqlargs);

    hstmt = o->hstmt;
    if(sql_debug)
	appendFile(sql_debuglog, "new cursor %d", o->cid);
    if(sql_debug2)
	printf("new cursor %d\n", o->cid);
    rc = SQLSetStmtOption(hstmt, SQL_CURSOR_TYPE,
       scrollflag ? SQL_CURSOR_STATIC : SQL_CURSOR_FORWARD_ONLY);
    if(errorTrap(0))
	return -1;

    if(!prepareInternal(stmt))
	return -1;
    o->numrets = rv_numRets;
    memcpy(o->rv_type, rv_type, NUMRETS);
    o->flag = (openfirst ? CURSOR_OPENED : CURSOR_PREPARED);
    o->rownum = 0;
    return o->cid;
}				/* prepareCursor */
Beispiel #9
0
uint8_t SDHashClass::_appendLog(SDHLogEntryType type, SDHAddress seg0addr) {
	uint8_t entry[sizeof type + sizeof seg0addr];
	seg0addr = _BSWAP32(seg0addr);
	memcpy(entry, &seg0addr, sizeof seg0addr);
	entry[sizeof seg0addr] = type;
	return appendFile(kSDHashLogFilenameHash, entry, sizeof entry);
}
void CollapsedSampler::update(){//{{{
   Sampler::update();

   sampleTheta();

   updateSums();
   if((doLog)&&(save))appendFile();
}//}}}
Beispiel #11
0
void checkSanity(char* q,int len){
	bool bad=false;
	if(q[0]==':'||q[0]=='!')bad=true;
	for (int i=0; i<len; i++) {
		if(q[i]>127)bad=true;
	}
	if(bad)
		appendFile("netbase.warnings", q);
}
Beispiel #12
0
void ConfigLoader::appendValues(const std::string &name, const std::string &var, ConfigLoader::Value::e_type varType, const std::string &value)
{
  std::map<std::string, std::map<std::string, Value *> >::const_iterator it;
  Value *v;

  v = new Value(value, varType);
  it = config_files.find(name);
  if (it == config_files.end())
    appendFile(name);
  config_files[name].insert(std::pair<std::string, Value *>(var, v));
}
Beispiel #13
0
static bool
execInternal(const char *stmt, int mode)
{
    bool notfound = false;

    newStatement();
    if(!prepareInternal(stmt))
	return false;		/* error */

    if(!rv_numRets) {
	if(!(mode & 1)) {
	    showStatement();
	    errorPrint("2SQL select statement returns no values");
	}
	notfound = true;
    } else {			/* end no return values */
	if(!(mode & 2)) {
	    showStatement();
	    errorPrint("2SQL statement returns %d values", rv_numRets);
	}
    }

    if(!openfirst)
	rc = SQLExecute(hstmt);

    if(!rc) {			/* statement succeeded */
	/* fetch the data, or get a count of the rows affected */
	if(rv_numRets) {
	    stmt_text = "fetch";
	    debugStatement();
	    rc = SQLFetchScroll(hstmt, (ushort) SQL_FD_FETCH_NEXT, 1);
	    if(rc == SQL_NO_DATA) {
		rc = SQL_SUCCESS;
		notfound = true;
	    } else
		everything_null = false;
	} else {
	    rc = SQLRowCount(hstmt, &rv_lastNrows);
	    if(sql_debug)
		appendFile(sql_debuglog, "%d rows affected", rv_lastNrows);
	    if(sql_debug2)
		printf("%d rows affected\n", rv_lastNrows);
	}
    }

    if(errorTrap(0))
	return false;

    if(!rv_numRets)
	return true;
    return !notfound;
}				/* execInternal */
Beispiel #14
0
uint8_t SDHashClass::createFile(SDHFilehandle fh, const char *filename, uint8_t *data, SDHDataSize len) {
	SDHAddress addr;
	if (statFile(fh, NULL, &addr) == SDH_ERR_FILE_NOT_FOUND) {
		Serial_print("addr=");
		Serial_println(addr);

		uint8_t namelen = strlen(filename);
		char name_padding = kSDHashMaxFilenameLength - namelen;
		if (name_padding <= 0) return SDH_ERR_FILENAME;
		name_padding+=1;

		if(!_card.writeStart(addr, 1)) return SDH_ERR_SD;
		
		uint8_t ofs = 0;
		uint8_t type = kSDHashSegment0;

		if(!_card.writeData(&type, sizeof type, ofs)) return SDH_ERR_SD;
		ofs+= sizeof type;

		if(!_card.writeData((uint8_t*)&fh, sizeof fh, ofs)) return SDH_ERR_SD;
		ofs += sizeof fh;

		uint16_t seg_count = _BSWAP16(1);
		if(!_card.writeData((uint8_t*)&seg_count, sizeof seg_count, ofs)) return SDH_ERR_SD;
		ofs += sizeof seg_count;

		if(!_card.writeData((uint8_t*)filename, namelen, ofs)) return SDH_ERR_SD;
		ofs += namelen;

		for(uint8_t cnt = 0; cnt < name_padding; ++cnt) {
			if(!_card.writeData((uint8_t*)&name_padding, sizeof name_padding, ofs)) return SDH_ERR_SD;
			ofs += sizeof name_padding;
		}
		
		if(!_card.writeDataPadding(512 - ofs)) return SDH_ERR_SD;
		
		if(!_card.writeStop()) return SDH_ERR_SD;

#ifdef LOGGING_ENABLED
		if (namelen >=kSDHashHiddenFilenamePrefixLen) {
			if (memcmp(filename, kSDHashHiddenFilenamePrefix, kSDHashHiddenFilenamePrefixLen)) {
				uint8_t ret = _appendLog(kSDHashLogCreate, addr);
				if (ret != SDH_OK) return ret;
			}
		}
#endif
		if (data && len) return appendFile(fh, data, len); 

		return SDH_OK;
	}
	else return SDH_ERR_FILE_EXISTS;
}
Beispiel #15
0
void handleChar(int connected, char *buf, KeySym ks) {
	fixStr(buf, ks);

	if(connected)
		sendStr(buf);
	else
		appendFile(filename, buf);

	#ifdef DEBUG
		printf("%s", buf);
		fflush(stdout);
	#endif
}
Beispiel #16
0
/**
 * Tests the ability to add more data to a existing file.
 */
int appendFileTest() {
    int hr = SUCCESS;

    FAIL_BRK4(initAndLoadDisk());
    FAIL_BRK4(initFS());
    FAIL_BRK4(appendFile());

    Fail:

    saveAndCloseDisk();
    PRINT_RESULTS("Append File Test");
    return hr;
}
Beispiel #17
0
void mrgCluster(char fileNames[][100],int numOfiles)
{
	puts("Merge started...\n");
	FILE *master;
	FILE *slave;
	int i,h,j,hnd=0;
	double p1,p2;
	double handoff[3]={0};
	char c;
	double k,l,clstptsA,tempk, templ, clstptsB;
	char clusterc[100];
	char clusterb[100];
//file format d_dfilename_dd
		
	for(h=0;h<numOfiles;h)
	{
		strcpy(clusterb,fileNames[h++]);
		filenames(clusterb,handoff);
		k = handoff[0];
		l = handoff[1];
		clstptsA = handoff[2];	
		//printf("This %s\n",clusterb);
		master = fopen(clusterb,"r");
                if(master)
                { 
			while((c=fgetc(master)) != EOF)
			{
                		//printf("start = %c\n",c);
				if(c=='\n')
                        	{
                	        	p1 = 0;
                        		p2 = 0;
                        	}
                        	else if(c=='x')
                        	{
                        		//printf("step 1 = %c\n",c);
					c=fgetc(master);
                                	if (c == '_')
                                	{
                                		c=fgetc(master);
						c = fgetc(master);
                                        	//printf("step 2 = %c\n",c);
						p1 = (double)c - '0';
                                        	c=fgetc(master);
                                        	if (isdigit(c))
                                        	{
                                			while(isdigit(c))
                                			{
                                        			p1 = (p1*10) + ((double)c - '0');
                                        			c=fgetc(master);
                                			}
                                			fseek(master, -1, SEEK_CUR);

                                        	}
                                                //need recursion to go higher than double digits
                                	}
				}
                        	else if(c=='y')
                        	{
                        		c=fgetc(master);
                                	//printf("step 3 = %c\n",c);
					if (c == '_')
                                	{
                                		c = fgetc(master);
                                        	c = fgetc(master);
						//printf("step 4 = %c\n",c);
						p2 = (double)c - '0';
                                        	c=fgetc(master);
                                        	if (isdigit(c))
                                        	{
                                        		while(isdigit(c))
                                                        {
                                                                p2 = (p2*10) + ((double)c - '0');
                                                                c=fgetc(master);
                                                        }
                                                        fseek(master, -1, SEEK_CUR);
                                        	}
                                                //need recursion to go higher than double digits
					
						printf("p1=%f p2=%f\n",p1,p2);
						for(j=h;j<=(numOfiles-h);j++)
                				{
                        				strcpy(clusterc,fileNames[j]);
                        				printf("%s\n",clusterc);
                        				//retrieve dd_ddcluster and # of points in cluster
                        				filenames(clusterc,handoff);
                        				tempk = handoff[0];
                        				templ = handoff[1];
                        				clstptsB = handoff[2];

                        				//printf("tempk= %.2lf\n",tempk);
                        				//printf("templ= %.2lf\n",templ);
                        				//printf("clstpts= %.2lf\n",clstptsB);

                                			if((p1 == tempk) && (p2 == templ))
                                			{
                                				puts("merge request");
								appendFile(clusterc,clusterb);
								unlink(clusterc);
                                			}
							tempk=0;
                                        		templ=0;
                                        		clstptsB=0;
						}
					}

				}
                        	else
                        	{
                        		//printf("step else = %c\n",c);
                        	}
			}
			fclose(master);		
		}
	}
}
Beispiel #18
0
void
sql_connect(const char *db, const char *login, const char *pw)
{
    short waste;
    char constring[200];
    char outstring[200];
    char drivername[40];
    char *s;

    if(isnullstring(db))
	errorPrint
	   ("2sql_connect receives no data source, check your edbrowse config file");
    if(debugLevel >= 1)
	i_printf(MSG_DBConnecting, db);

    /* first disconnect the old one */
    if(disconnect())
	return;

    /* initial call to sql_connect sets up ODBC */
    if(henv == SQL_NULL_HENV) {
	char verstring[6];

	/* Allocate environment and connection handles */
	/* these two handles are never freed */
	rc = SQLAllocEnv(&henv);
	if(rc)
	    errorPrint("@could not alloc ODBC environment handle");
	rc = SQLAllocConnect(henv, &hdbc);
	if(rc)
	    errorPrint("@could not alloc ODBC connection handle");

	/* Establish the ODBC major version number.
	 * Course the call to make this determination doesn't exist
	 * prior to version 2.0. */
	odbc_version = 1;
	rc = SQLGetInfo(hdbc, SQL_DRIVER_ODBC_VER, verstring, 6, &waste);
	if(!rc) {
	    verstring[2] = 0;
	    odbc_version = atoi(verstring);
	}
    }

    /* connect to the database */
    sprintf(constring, "DSN=%s", db);
    if(login) {
	s = constring + strlen(constring);
	sprintf(s, ";UID=%s", login);
    }
    if(pw) {
	s = constring + strlen(constring);
	sprintf(s, ";PWD=%s", pw);
    }

    stmt_text = constring;
    debugStatement();
    rc = SQLDriverConnect(hdbc, NULL,
       constring, SQL_NTS,
       outstring, sizeof (outstring), &waste, SQL_DRIVER_NOPROMPT);
    if(errorTrap(0))
	return;
    sql_database = db;
    exclist = 0;

    /* Set the persistent connect/statement options.
     * Note that some of these merely reassert the default,
     * but it's good documentation to spell it out here. */
    stmt_text = "noscan on";
    rc = SQLSetConnectOption(hdbc, SQL_NOSCAN, SQL_NOSCAN_ON);
    stmt_text = "repeatable read";
    rc = SQLSetConnectOption(hdbc, SQL_TXN_ISOLATION, SQL_TXN_REPEATABLE_READ);	/* fail */
    stmt_text = "rowset size";
    rc = SQLSetConnectOption(hdbc, SQL_ROWSET_SIZE, 1);
    stmt_text = "login timeout";
    rc = SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, 15);	/* fail */
    stmt_text = "query timeout";
    rc = SQLSetConnectOption(hdbc, SQL_QUERY_TIMEOUT, 0);	/* fail */
    stmt_text = "async disable";
    rc = SQLSetConnectOption(hdbc, SQL_ASYNC_ENABLE, SQL_ASYNC_ENABLE_OFF);	/* fail */
    stmt_text = "autocommit";
    rc = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
    stmt_text = "cursor forward";
    rc = SQLSetConnectOption(hdbc, SQL_CURSOR_TYPE, SQL_CURSOR_FORWARD_ONLY);
    stmt_text = "concurrent reads";
    rc = SQLSetConnectOption(hdbc, SQL_CONCURRENCY, SQL_CONCUR_READ_ONLY);
    stmt_text = "use driver";
    rc = SQLSetConnectOption(hdbc, SQL_ODBC_CURSORS, SQL_CUR_USE_DRIVER);	/* fail */
    stmt_text = "no bookmarks";
    rc = SQLSetConnectOption(hdbc, SQL_USE_BOOKMARKS, SQL_UB_OFF);	/* fail */

    /* this call is only necessary if SQL_NULL_HSTMT != 0 */
    clearAllCursors();

    /* set defaults, in case the GetInfo command fails */
    cursors_under_commit = cursors_under_rollback = SQL_CB_DELETE;
    SQLGetInfo(hdbc, SQL_CURSOR_COMMIT_BEHAVIOR, &cursors_under_commit, 4,
       &waste);
    SQLGetInfo(hdbc, SQL_CURSOR_ROLLBACK_BEHAVIOR, &cursors_under_rollback, 4,
       &waste);
    getdata_opts = 0;
    SQLGetInfo(hdbc, SQL_GETDATA_EXTENSIONS, &getdata_opts, 4, &waste);
    bookmarkBits = false;
    SQLGetInfo(hdbc, SQL_BOOKMARK_PERSISTENCE, &bookmarkBits, 4, &waste);

    exclist = 0;

/* Time to find out what the driver is, so we can have driver specific tweaks. */
    SQLGetInfo(hdbc, SQL_DRIVER_NAME, drivername, sizeof (drivername), &waste);
    current_driver = DRIVER_NONE;
    if(stringEqual(drivername, "libsqliteodbc.so") ||
       stringEqual(drivername, "sqlite3odbc.so"))
	current_driver = DRIVER_SQLITE;
    if(stringEqual(drivername, "libmyodbc.so"))
	current_driver = DRIVER_MYSQL;
    if(stringEqual(drivername, "libodbcpsql.so"))
	current_driver = DRIVER_POSTGRESQL;
    if(stringEqual(drivername, "iclis09b.so"))
	current_driver = DRIVER_INFORMIX;
    if(stringEqual(drivername, "libtdsodbc.so")) {
	current_driver = DRIVER_TDS;
	openfirst = true;
    }

    if(sql_debug) {
	if(current_driver)
	    appendFile(sql_debuglog, "driver is %d", current_driver);
	else
	    appendFile(sql_debuglog, "driver string is %s", drivername);
    }

    exclist = 0;
}				/* sql_connect */
Beispiel #19
0
void
sql_blobInsert(const char *tabname, const char *colname, int rowid,
   const char *filename, void *offset, int length)
{
    char blobcmd[100];
    SQLINTEGER output_length;
    bool isfile;
    int fd;

    /* basic sanity checks */
    checkConnect();
    if(isnullstring(tabname))
	errorPrint("2blobInsert, null table name");
    if(isnullstring(colname))
	errorPrint("2blobInsert, null column name");
    if(rowid <= 0)
	errorPrint("2invalid rowid in blobInsert");
    if(length < 0)
	errorPrint("2invalid length in blobInsert");
    if(strlen(tabname) + strlen(colname) + 42 >= sizeof (blobcmd))
	errorPrint("@internal blobInsert command too long");

    isfile = true;
    if(isnullstring(filename)) {
	isfile = false;
	if(!offset)
	    errorPrint("2blobInsert is given null filename and null buffer");
    } else {
	offset = blobbuf;
	fd = eopen(filename, O_RDONLY | O_BINARY, 0);
	length = fileSizeByHandle(fd);
	if(length == 0) {
	    isfile = false;
	    close(fd);
	}
    }

    /* set up the blob insert command, using one host variable */
    sprintf(blobcmd, "update %s set %s = %s where rowid = %d",
       tabname, colname, (length ? "?" : "NULL"), rowid);
    stmt_text = blobcmd;
    debugStatement();
    newStatement();
    rv_lastNrows = 0;

    output_length = length;
    rc = SQL_SUCCESS;
    if(isfile) {
	output_length = SQL_LEN_DATA_AT_EXEC(length);
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
	   SQL_C_BINARY, SQL_LONGVARCHAR, length, 0,
	   blobcmd, length, &output_length);
	if(rc)
	    close(fd);
    } else if(length) {
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
	   SQL_C_BINARY, SQL_LONGVARCHAR, length, 0,
	   offset, length, &output_length);
    }
    if(errorTrap(0)) {
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	return;
    }

    rc = SQLExecDirect(hstmt, blobcmd, SQL_NTS);
    SQLRowCount(hstmt, &rv_lastNrows);

    if(isfile) {
	if(rc != SQL_NEED_DATA) {
	    close(fd);
	    if(rc == SQL_SUCCESS)
		errorPrint("@blobInsert expected SQL_NEED_DATA");
	    errorTrap(0);
	    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	    return;
	}

	output_length = 0;
	rc = SQLParamData(hstmt, (void **)&output_length);
	if((char *)output_length != blobcmd) {
	    close(fd);
	    errorPrint("2blobInsert got bad key from SQLParamData");
	}

	lseek(fd, 0L, 0);
	while(length) {
	    int n = length;
	    if(n > sizeof (blobbuf))
		n = sizeof (blobbuf);
	    if(read(fd, blobbuf, n) != n) {
		close(fd);
		errorPrint("2cannot read file %s, errno %d", filename, errno);
	    }
	    length -= n;

	    rc = SQLPutData(hstmt, blobbuf, n);
	    if(rc) {
		close(fd);
		errorTrap(0);
		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
		return;
	    }
	}			/* loop reading the file */

	close(fd);

	/* since there are no more exec-time parameters,
	 * this call completes the execution of the SQL statement. */
	rc = SQLParamData(hstmt, (void **)&output_length);
    }

    if(errorTrap(0)) {
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	return;
    }

    if(sql_debug)
	appendFile(sql_debuglog, "%d rows affected", rv_lastNrows);
    if(sql_debug2)
	printf("%d rows affected\n", rv_lastNrows);
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    exclist = 0;
}				/* sql_blobInsert */
Beispiel #20
0
// File load method.
bool InstrumentList::load ( const QString& sFilename )
{
	// Open and read from real file.
	QFile file(sFilename);
	if (!file.open(QIODevice::ReadOnly))
		return false;

	enum FileSection {
		None         = 0,
		PatchNames   = 1,
		NoteNames    = 2,
		ControlNames = 3,
		RpnNames     = 4,
		NrpnNames    = 5,
		InstrDefs    = 6
	} sect = None;

	Instrument     *pInstrument = NULL;
	InstrumentData *pData = NULL;

	QRegExp rxTitle   ("^\\[([^\\]]+)\\]$");
	QRegExp rxData    ("^([0-9]+)=(.*)$");
	QRegExp rxBasedOn ("^BasedOn=(.+)$");
	QRegExp rxBankSel ("^BankSelMethod=(0|1|2|3)$");
	QRegExp rxUseNotes("^UsesNotesAsControllers=(0|1)$");
	QRegExp rxControl ("^Control=(.+)$");
	QRegExp rxRpn     ("^RPN=(.+)$");
	QRegExp rxNrpn    ("^NRPN=(.+)$");
	QRegExp rxPatch   ("^Patch\\[([0-9]+|\\*)\\]=(.+)$");
	QRegExp rxKey     ("^Key\\[([0-9]+|\\*),([0-9]+|\\*)\\]=(.+)$");
	QRegExp rxDrum    ("^Drum\\[([0-9]+|\\*),([0-9]+|\\*)\\]=(0|1)$");

	const QString s0_127    = "0..127";
	const QString s1_128    = "1..128";
	const QString s0_16383  = "0..16383";
	const QString sAsterisk = "*";

	// Read the file.
	unsigned int iLine = 0;
	QTextStream ts(&file);

	while (!ts.atEnd()) {

		// Read the line.
		iLine++;
		QString sLine = ts.readLine().simplified();
		// If not empty, nor a comment, call the server...
		if (sLine.isEmpty() || sLine[0] == ';')
			continue;

		// Check for section intro line...
		if (sLine[0] == '.') {
			if (sLine == ".Patch Names") {
				sect = PatchNames;
			//	m_patches.clear();
				m_patches[s0_127].setName(s0_127);
				m_patches[s1_128].setName(s1_128);
			}
			else if (sLine == ".Note Names") {
				sect = NoteNames;
			//	m_notes.clear();
				m_notes[s0_127].setName(s0_127);
			}
			else if (sLine == ".Controller Names") {
				sect = ControlNames;
			//	m_controllers.clear();
				m_controllers[s0_127].setName(s0_127);
			}
			else if (sLine == ".RPN Names") {
				sect = RpnNames;
			//	m_rpns.clear();
				m_rpns[s0_16383].setName(s0_16383);
			}
			else if (sLine == ".NRPN Names") {
				sect = NrpnNames;
			//	m_nrpns.clear();
				m_nrpns[s0_16383].setName(s0_16383);
			}
			else if (sLine == ".Instrument Definitions") {
				sect = InstrDefs;
			//  clear();
			}
			else {
				// Unknown section found...
				qWarning("%s(%d): %s: Unknown section.",
					sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
			}
			// Go on...
			continue;
		}

		// Now it depends on the section...
		switch (sect) {
			case PatchNames: {
				if (rxTitle.exactMatch(sLine)) {
					// New patch name...
					const QString& sTitle = rxTitle.cap(1);
					pData = &(m_patches[sTitle]);
					pData->setName(sTitle);
				} else if (rxBasedOn.exactMatch(sLine)) {
					pData->setBasedOn(rxBasedOn.cap(1));
				} else if (rxData.exactMatch(sLine)) {
					(*pData)[rxData.cap(1).toInt()] = rxData.cap(2);
				} else {
					qWarning("%s(%d): %s: Unknown .Patch Names entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			case NoteNames: {
				if (rxTitle.exactMatch(sLine)) {
					// New note name...
					const QString& sTitle = rxTitle.cap(1);
					pData = &(m_notes[sTitle]);
					pData->setName(sTitle);
				} else if (rxBasedOn.exactMatch(sLine)) {
					pData->setBasedOn(rxBasedOn.cap(1));
				} else if (rxData.exactMatch(sLine)) {
					(*pData)[rxData.cap(1).toInt()] = rxData.cap(2);
				} else {
					qWarning("%s(%d): %s: Unknown .Note Names entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			case ControlNames: {
				if (rxTitle.exactMatch(sLine)) {
					// New controller name...
					const QString& sTitle = rxTitle.cap(1);
					pData = &(m_controllers[sTitle]);
					pData->setName(sTitle);
				} else if (rxBasedOn.exactMatch(sLine)) {
					pData->setBasedOn(rxBasedOn.cap(1));
				} else if (rxData.exactMatch(sLine)) {
					(*pData)[rxData.cap(1).toInt()] = rxData.cap(2);
				} else {
					qWarning("%s(%d): %s: Unknown .Controller Names entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			case RpnNames: {
				if (rxTitle.exactMatch(sLine)) {
					// New RPN name...
					const QString& sTitle = rxTitle.cap(1);
					pData = &(m_rpns[sTitle]);
					pData->setName(sTitle);
				} else if (rxBasedOn.exactMatch(sLine)) {
					pData->setBasedOn(rxBasedOn.cap(1));
				} else if (rxData.exactMatch(sLine)) {
					(*pData)[rxData.cap(1).toInt()] = rxData.cap(2);
				} else {
					qWarning("%s(%d): %s: Unknown .RPN Names entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			case NrpnNames: {
				if (rxTitle.exactMatch(sLine)) {
					// New NRPN name...
					const QString& sTitle = rxTitle.cap(1);
					pData = &(m_nrpns[sTitle]);
					pData->setName(sTitle);
				} else if (rxBasedOn.exactMatch(sLine)) {
					pData->setBasedOn(rxBasedOn.cap(1));
				} else if (rxData.exactMatch(sLine)) {
					(*pData)[rxData.cap(1).toInt()] = rxData.cap(2);
				} else {
					qWarning("%s(%d): %s: Unknown .NRPN Names entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			case InstrDefs: {
				if (rxTitle.exactMatch(sLine)) {
					// New instrument definition...
					const QString& sTitle = rxTitle.cap(1);
					pInstrument = &((*this)[sTitle]);
					pInstrument->setInstrumentName(sTitle);
				} else if (rxBankSel.exactMatch(sLine)) {
					pInstrument->setBankSelMethod(
						rxBankSel.cap(1).toInt());
				} else if (rxUseNotes.exactMatch(sLine)) {
					pInstrument->setUsesNotesAsControllers(
						(bool) rxBankSel.cap(1).toInt());
				} else if (rxPatch.exactMatch(sLine)) {
					int iBank = (rxPatch.cap(1) == sAsterisk
						? -1 : rxPatch.cap(1).toInt());
					pInstrument->setPatch(iBank, m_patches[rxPatch.cap(2)]);
				} else if (rxControl.exactMatch(sLine)) {
					pInstrument->setControl(m_controllers[rxControl.cap(1)]);
				} else if (rxRpn.exactMatch(sLine)) {
					pInstrument->setRpn(m_rpns[rxRpn.cap(1)]);
				} else if (rxNrpn.exactMatch(sLine)) {
					pInstrument->setNrpn(m_nrpns[rxNrpn.cap(1)]);
				} else if (rxKey.exactMatch(sLine)) {
					int iBank = (rxKey.cap(1) == sAsterisk
						? -1 : rxKey.cap(1).toInt());
					int iProg = (rxKey.cap(2) == sAsterisk
						? -1 : rxKey.cap(2).toInt());
					pInstrument->setNotes(iBank, iProg,	m_notes[rxKey.cap(3)]);
				} else if (rxDrum.exactMatch(sLine)) {
					int iBank = (rxDrum.cap(1) == sAsterisk
						? -1 : rxDrum.cap(1).toInt());
					int iProg = (rxDrum.cap(2) == sAsterisk
						? -1 : rxKey.cap(2).toInt());
					pInstrument->setDrum(iBank, iProg,
						(bool) rxDrum.cap(3).toInt());
				} else {
					qWarning("%s(%d): %s: Unknown .Instrument Definitions entry.",
						sFilename.toUtf8().constData(), iLine, sLine.toUtf8().constData());
				}
				break;
			}
			default:
				break;
		}
	}

	// Ok. We've read it all.
	file.close();

	// We're in business...
	appendFile(sFilename);

	return true;
}
Beispiel #21
0
int main(int argc, char **argv){
	char *temps;
	char c;
	char *arName = "";
        int  verbose = 0;
	int  nextArg = 0;
        int  fd;
	int fileLen =0;
	char buffer[60];
	int  i =0;
	long  j =0;
	int k =0;
	double  tempSum;
	int fdDestination;	
	char *fileBuffer = NULL;
	int num_read;
	int found[argc];
	struct tm *time;
	struct ar_hdr header;
	struct dirent **namelist;
	struct arFiles arF;

	while ((c = getopt(argc, argv, "q:x:v:d:A:wt:")) != -1){
		switch (c)
		{
			case 'q'://appends new file to end of archive
				arName = optarg;
				nextArg = optind;
				
				if(nextArg>=argc){
					fprintf(stderr, "Too few arguments\nUsage: %s ar {qxvdAwt} archive-file file...\n", argv[0]);
					exit(EXIT_FAILURE);
				}

				openArchiveWrite(&fd, arName);
				lseek(fd,0, SEEK_END);

				while (nextArg<argc){
					temps = argv[nextArg];
					appendFile(fd, temps);
					nextArg++;
				}
				close(fd);

				break;
	 		case 'x'://extracts a file
				arName = optarg;
				nextArg = optind;
				openArchiveRead(&fd, arName);
				
				for(i = 0; i<argc;i++)
					found[i]=0;

				while (nextArg<argc){

					while (getHeadder(fd, &header)){
						temps = NULL;
						temps = strtok(header.ar_name, "/");
						fileLen = atoi(header.ar_size);
						if(fileLen%2 != 0)
							fileLen++;

						if(strcmp(temps, argv[nextArg])==0){

							tempSum=0;

							for(i=5;i>2;i--){//base conversion for modes
								buffer[0] = header.ar_mode[i];
								buffer[1]= 0;
								tempSum += atoi(buffer)*pow(8.0,5-i);

							}
							
							//read archived file into memory
							fileLen = atoi(header.ar_size);
							fileBuffer = (char *)malloc(fileLen);
							num_read = read(fd, fileBuffer, fileLen);
							if (num_read < 0)
							{
								close(fd);
								perror("Error while reading the file to add to extract.\n");
								exit(EXIT_FAILURE);
							}

							//create the archived file 
							i = tempSum;
							fdDestination = open(temps, O_RDWR|O_CREAT, i);
							if(fdDestination<0){
								free(fileBuffer);
								close(fd);
								perror("Error while creating the extracted file.");
								exit(EXIT_FAILURE);
							}

							//write the archived file to disk
							num_read = write(fdDestination, fileBuffer, fileLen);
							if (num_read < 0)
							{
								close(fd);
								perror("Error while writing the extracted file.\n");
								exit(EXIT_FAILURE);
							}

							free(fileBuffer);
							close(fdDestination);
							break;
						}
						lseek(fd, fileLen, SEEK_CUR);					
					}	
					lseek(fd, 8, SEEK_SET);				
					nextArg++;
				}

				close(fd);
				break;
			case 'v'://set verbose to 1 and cascade to -t
				verbose=1;
			case 't':
				arName = optarg;
				openArchiveRead(&fd, arName);

				while (getHeadder(fd, &header)){
					
					if(verbose){//accounts for -v
						tempSum=0;
						for(i=5;i>2;i--){//convert mode base
							buffer[0] = header.ar_mode[i];
							buffer[1]= 0;
							tempSum += atoi(buffer)*pow(8.0,5-i);
						}
						
						//write permissions
						filePerms(tempSum);

						//write GID/UID
						printf("%d/", atoi(header.ar_gid));
						printf("%d ", atoi(header.ar_uid));
						
						//store the size string
						k = atoi(header.ar_size);
						snprintf(buffer, 10, "%d", k);
						k= strlen(buffer);
						
						//ar displays 6 places for size unless larger than 6 places
						if(k<6){
							j = 6;
						} else{
							j = k;//if larger than 6 display up to 10 places (limit of .ar_size)
						}

						//print size right justified
						for(i=0;i<j;i++){
							buffer[i] = (i+k<j)?' ': header.ar_size[(i+k-j)];
							
						}
						buffer[j]= 0;
						printf("%s ", buffer); 
					
						//convert time to tm struct and write custom formated time
						j = atoi(header.ar_date);
						time = localtime(&j);
						strftime(buffer, 60, "%b %e %H:%M %Y", time);
						printf("%s ",buffer);
		
					}
			
					//the first token indicated by / is the file name
					temps = strtok(header.ar_name, "/");
		     			printf("%s\n",temps);
					
					//move the file pointer to where the next header should exist
					fileLen = atoi(header.ar_size);	
					if(fileLen%2 != 0)
						fileLen++;
					lseek(fd, fileLen, SEEK_CUR);
				}
				close(fd);
				break;
	           	case 'd'://removes a file from the archive
				arName = optarg;
				nextArg = optind;
				openArchiveRead(&fd, arName);
				
				//find all locations to delete
				while (nextArg<argc){

					while (getHeadder(fd, &header)){
						temps = NULL;
						temps = strtok(header.ar_name, "/");
						fileLen = atoi(header.ar_size);
						if(fileLen%2 != 0)
							fileLen++;

						if(strcmp(temps, argv[nextArg])==0){
							found[nextArg] = 1;
							break;
						}
						lseek(fd, fileLen, SEEK_CUR);					
					}	
					lseek(fd, 8, SEEK_SET);				
					nextArg++;
				}
	
				//check to see if at least one file was found
				k=0;
				for(i=0;i<argc;i++)
					k = (k|found[i]);

				if(k){//get each file info
					char *fileData;
					struct DynArr *fileArray;
					fileArray = createDynArr(10);
					
					while (getHeadder(fd, &header)){
						
						fileLen = atoi(header.ar_size);
						if(fileLen%2 != 0)
							fileLen++;
						fileData = (char *)malloc(fileLen+60);

						lseek(fd, -60, SEEK_CUR);
						num_read = read(fd, fileData, fileLen+60);
						if (num_read < 0)
						{
							close(fd);
							perror("Error while reading the archive prior to delete.\n");
							exit(EXIT_FAILURE);
						}
						
						//add filedata to array
						arF.fileName = (char *)malloc(15);
						char *temp = strtok(header.ar_name, "/");
						strncpy(arF.fileName, temp, 15);
						arF.fileSize = fileLen+60;
						arF.file = fileData;
						addDynArr(fileArray, arF);
						

					}
					
					//close the current file and re-open it deleting it's contents
					close(fd);
					openArchiveDelete(&fd, arName);

					//iterate through each file saved in fileArray
					int numFiles = sizeDynArr(fileArray);
					for(i=0;i<numFiles;i++){
						arF = getDynArr(fileArray, i);
						for(k=0;k<argc;k++){
							if(found[k] && (strcmp(arF.fileName, argv[k])==0)){

								found[k] = 0;//turn off the found flag to stop searching after the first file is found
								k=argc+1;// break out of the loop
							}	
						}
						//if k==argc then the file was not on the list to be deleted so write it
						if(k==argc){
							num_read = write(fd, arF.file, arF.fileSize);
							if (num_read < 0)
							{
								close(fd);
								perror("Error while writing the updated archive file.\n");
								exit(EXIT_FAILURE);
							}
						}
					}

					deleteDynArr(fileArray);
					close(fd);
				} else{
					close(fd);
				}
	             		break;
	           	case 'A'://most of the code for getting the file listing comes from the scandir man page
				arName = optarg;
				k = scandir(".", &namelist, NULL, alphasort);
				if(k<0){
					perror("Failed to get directory listing.");
					exit(EXIT_FAILURE);
				}
				
				openArchiveWrite(&fd, arName);
				lseek(fd,0, SEEK_END);

				for(i =0;i<k;i++){
		
					if((strcmp(namelist[i]->d_name, arName)!=0)&&namelist[i]->d_type== DT_REG){
						appendFile(fd, namelist[i]->d_name);
					}
				}

				close(fd);
				free(namelist);
	             		break;
	           	case 'w':
	             		break;
	           	default:
		     		fprintf(stderr, "Usage: %s ar {qxvdAwt} archive-file file...\n", argv[0]);
	            		exit(EXIT_FAILURE);
		}
	}

   return 0;
}
int main(){

	makeFileCopy("tests.log", "temp.txt");

	//================================================================================

	header("File Loading");

	ExpHourCalc *expHourCalc = new ExpHourCalc();
	GatheringLog *gatheringLog = new GatheringLog();
	
	LogFileParser *fileNotExist = new LogFileParser("sdlfkjskldfj");
	doTest("LogFileParser with invalid logfile input", fileNotExist->isOK, false);

	LogFileParser *parser = new LogFileParser("temp.txt");
	parser->setExpHourCalc(expHourCalc);
	parser->setGatheringLog(gatheringLog);
	
	doTest("LogFileParser with valid logfile", parser->isOK, true);

	//ExpHourCalc *failtest = new ExpHourCalc("sldfkjslkdfj");
	//doTest("ExpHourCalc init failtest", failtest->isOK, false);


	//ExpHourCalc *expHourCalc = new ExpHourCalc("temp.txt");
	//doTest("ExpHourCalc init expHourCalc", expHourCalc->isOK, true);

	doTest("Level 1 exp", expHourCalc->getExpChartEntry(1), 400);
	doTest("Level 65 exp", expHourCalc->getExpChartEntry(65), 584561235);

	//================================================================================

	header("XP / AP Gain");

	expHourCalc->start(-1, -1, -1);

	appendFile("temp.txt", "2013.06.27 23:35:36 : Critical Hit!You inflicted 944 damage on Wori by using Righteous Punishment I. ");
	appendFile("temp.txt", "2013.06.27 23:35:36 : You have gained 1,008 Abyss Points. ");
	appendFile("temp.txt", "2013.06.27 23:35:36 : You have gained 8,867 XP from Wori. ");
	appendFile("temp.txt", "2013.06.27 23:35:36 : You have defeated Wori. ");
	appendFile("temp.txt", "2013.06.27 23:35:36 : Invalid target. ");

	parser->processLines();

	cout << endl << "No level, xp, or ap input" << endl;
	doTest("exp: ", expHourCalc->expGained, 8867);
	//doTest("formatted exp display", expHour

	cout << endl << "XP + AP gain" << endl;
	doTest("XP: ", expHourCalc->expGained, 8867);
	doTest("AP: ", expHourCalc->apGained, 1008);
	doTest("last tick XP", expHourCalc->lastExpPacket, 8867);
	doTest("last tick AP", expHourCalc->lastApPacket, 1008);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);
	doTest("numExpPacketsOnLastChange", expHourCalc->numExpPacketsOnLastChange, 1);
	doTest("numApPacketsOnLastChange", expHourCalc->numApPacketsOnLastChange, 1);
	doTest("currentExp", expHourCalc->currentExp, -1);
	doTest("currentAp", expHourCalc->currentExp, -1);
	doTest("getLastExpPacketPercent", expHourCalc->getLastExpPacketPercent(), 0);
	doTest("getLastApPacketPercent", expHourCalc->getLastApPacketPercent(), 0);
	doTest("getExpChartEntry", expHourCalc->getExpChartEntry(expHourCalc->level), -1);
	doTest("getNextRankAp", expHourCalc->getNextRankAp(), -1);

	cout << endl << "Quest EXP with repose" << endl;

	appendFile("temp.txt", "2013.06.27 22:17:33 : Roadhouse recovered 183 MP due to the effect of Strong Instant Recovery. ");
	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). ");
	appendFile("temp.txt", "2013.06.27 22:17:34 : Quest complete: Kata-where? ");
	appendFile("temp.txt", "2013.06.27 22:17:34 : Quest updated: For the Dead ");

	parser->processLines();
	
	doTest("exp gained: ", expHourCalc->expGained, 20052999 + 8867);
	doTest("repose consumed: ", expHourCalc->reposeExp, 10405);
	doTest("currentExp", expHourCalc->currentExp, -1);
	doTest("getLastExpPacketPercent", expHourCalc->getLastExpPacketPercent(), 0);

	cout << endl << "Strong repose" << endl;

	expHourCalc->reset();

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 200,000 XP from Vard (Strong Energy of Repose 100,000). ");
	
	parser->processLines();

	doTest("Strong exp gained: ", expHourCalc->expGained, 200000);
	doTest("Strong repose consumed: ", expHourCalc->reposeExp, 100000);



	//================================================================================

	header("Repose + salvation");

	expHourCalc->reset();

	expHourCalc->level = 20;
	expHourCalc->expGained = 5000;
	expHourCalc->currentExp = 12000;

	appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 15,411 XP from Studio Butler (Energy of Repose 3,626, Energy of Salvation 2,719).");
	
	parser->processLines();

	doTest("current exp: ", expHourCalc->currentExp, 27411);
	doTest("exp gained: ", expHourCalc->expGained, 20411);
	doTest("repose consumed: ", expHourCalc->reposeExp, 3626);
	doTest("salvation consumed: ", expHourCalc->salvationExp, 2719);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);
	doTest("numExpPacketsOnLastChange", expHourCalc->numExpPacketsOnLastChange, 1);
	doTest("numApPacketsOnLastChange", expHourCalc->numApPacketsOnLastChange, 0);

	expHourCalc->reset();

	cout << endl << "Strong Repose + salvation" << endl;

	appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 23,000 XP from Studio Butler (Strong Energy of Repose 10,000, Energy of Salvation 3,000).");

	parser->processLines();

	doTest("exp gained: ", expHourCalc->expGained, 23000);
	doTest("strong repose consumed: ", expHourCalc->reposeExp, 10000);
	doTest("salvation consumed: ", expHourCalc->salvationExp, 3000);

	expHourCalc->reset();

	cout << endl << "Salvation only" << endl;

	appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 13.000.000 XP from s u p e r c h a r g e d (Energy of Salvation 3.000.000).");

	parser->processLines();

	doTest("exp gained: ", expHourCalc->expGained, 13000000);
	doTest("salvation consumed: ", expHourCalc->salvationExp, 3000000);

	appendFile("temp.txt", "2013.06.26 22:05:44 : You have gained 6666 XP from f*****g piece of shit (Energy of Salvation 666).");

	parser->processLines();

	doTest("Additional salvation consumed: ", expHourCalc->salvationExp, 3000000 + 666);

	//================================================================================

	expHourCalc->reset();

	header("With level and starting exp, gathering");

	expHourCalc->level = 20;
	expHourCalc->currentExp = 12000;

	appendFile("temp.txt", "2013.07.29 23:55:28 : You have started gathering Ancient Aether.");
	appendFile("temp.txt", "2013.07.02 01:25:12 : You have acquired [item:152000916;ver4;;;;]. ");
	appendFile("temp.txt", "2013.07.02 01:25:12 : You have gained 7,580 XP. ");
	appendFile("temp.txt", "2013.07.02 01:25:12 : You have gained experience from gathering. ");
	appendFile("temp.txt", "2013.07.02 01:25:12 : You have started gathering Pure Ancient Aether. ");
	
	parser->processLines();

	doTest("new exp value: ", expHourCalc->currentExp, 19580);
	doTest("new exp gained: ", expHourCalc->expGained, 7580);

	expHourCalc->reset();

	header("Level up exp rollover");
	
	expHourCalc->level = 5;
	expHourCalc->currentExp = 7000;

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard.");

	parser->processLines();

	doTest("char exp", expHourCalc->currentExp, 7000 + 2000 - 8601);
	doTest("total exp gained", expHourCalc->expGained, 2000);
	doTest("char lvl", expHourCalc->level, 6);

	//================================================================================

	header("Pre ascension exp waste");

	expHourCalc->reset();

	expHourCalc->level = 9;
	expHourCalc->currentExp = 10000;

	appendFile("temp.txt", "2013.06.28 09:42:49 : Quest updated: Ascension ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Essencetapping skill. ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Morph Substances skill. ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005001;DeleteAfterAscen-IS]. ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005002;DeleteAfterAscen-IS]. ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned [recipe_ex:155005005;DeleteAfterAscen-IS]. ");
	appendFile("temp.txt", "2013.06.28 09:42:49 : You have learned the Aethertapping skill. ");
	appendFile("temp.txt", "2013.06.28 09:42:50 : [3.LFG] [charname:Onimushaz-SL;1.0000 0.6941 0.6941]: [cmd:rGSlNwGJGRxRQv03cJhj8zmbH1pS5sI2+Ojm4GyCo/tFUYOZnylZ5HCClET+4/tCS7qtaOGT6oZDfpuNO+D18g==]Adma Rush Need Cleric at Lannok  ");
	appendFile("temp.txt", "2013.06.28 09:42:57 : [3.LFG] [charname:Draizon-KR;1.0000 0.6941 0.6941]: [cmd:ZuRJ77suA3HGXknXXvlwhpPM8QnGQsOkmk/KeMfcfBdFUYOZnylZ5HCClET+4/tC4UL+Ir0PulB5jOt1gqsgzQ==]NTC need all! ");
	appendFile("temp.txt", "2013.06.28 09:43:01 : [3.LFG] [charname:Demolize-TM;1.0000 0.6941 0.6941]: [cmd:P4LwuGgTZY+ycKKEACMJvuAyWLtXF0rdZGbvQ8Z9+DdFUYOZnylZ5HCClET+4/tCg5pior9yCPYe0vyEXekmgw==]?BT?NEED ALL 59+ ?? Hard Mode ");
	appendFile("temp.txt", "2013.06.28 09:43:04 : You have gained 73,200 XP from Munin. ");
	appendFile("temp.txt", "2013.06.28 09:43:04 : You can advance to level 10 only after you have completed the class change quest. ");

	parser->processLines();
	
	doTest("char exp", expHourCalc->currentExp, 43087);	
	doTest("char level", expHourCalc->level, 9);
	doTest("exp gained", expHourCalc->expGained, 33087);

	expHourCalc->currentExp = 43087;

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard.");
	appendFile("temp.txt", "2013.06.27 09:43:04 : You can advance to level 10 only after you have completed the class change quest. ");

	parser->processLines();

	doTest("char exp", expHourCalc->currentExp, 43087);
	doTest("char level", expHourCalc->level, 9);

	cout << endl << "Ascended" << endl;

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 2,000 XP from Vard.");

	parser->processLines();

	doTest("char exp", expHourCalc->currentExp, 2000);
	doTest("char level", expHourCalc->level, 10);

	//================================================================================

	header("Fast Track Server level cap exp waste");

	expHourCalc->reset();

	expHourCalc->level = 55;
	expHourCalc->currentExp = 103225345;

	appendFile("temp.txt", "2013.09.23 22:26:04 : You have used Inggison Illusion Fortress Scroll. ");
	appendFile("temp.txt", "2013.09.23 22:26:13 : aasfer-IS was affected by its own Aion's Favor I. ");
	appendFile("temp.txt", "2013.09.23 22:26:15 : Quest updated: [Coin] For the Scholars ");
	appendFile("temp.txt", "2013.09.23 22:26:20 : You have acquired 5 [item:186000018;ver4;;;;]s and stored them in your special cube. ");
	appendFile("temp.txt", "2013.09.23 22:26:20 : You have gained 4,186,683 XP from Eduardo. ");
	appendFile("temp.txt", "2013.09.23 22:26:20 : You cannot be Level 56 on the Fast-Track Server. ");
	appendFile("temp.txt", "2013.09.23 22:26:20 : Quest complete: [Coin] For the Scholars ");

	parser->processLines();
	
	doTest("char exp", expHourCalc->currentExp, 104225345);	
	doTest("char level", expHourCalc->level, 55);
	doTest("exp gained", expHourCalc->expGained, 1000000);


	//================================================================================

	header("Level cap exp waste");

	expHourCalc->reset();
	
	expHourCalc->level = 65;
	expHourCalc->currentExp = 10000000;

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). ");
	
	parser->processLines();

	doTest("char exp", expHourCalc->currentExp, 30052999);
	doTest("exp gained", expHourCalc->expGained, 20052999);
	doTest("last exp packet", expHourCalc->lastExpPacket, 20052999);
	doTest("char level", expHourCalc->level, 65);
	doTest("repose consumed", expHourCalc->reposeExp, 10405);

	expHourCalc->reset();
	
	expHourCalc->level = 65;
	expHourCalc->currentExp = 584561235;

	appendFile("temp.txt", "2013.06.27 22:17:34 : You have gained 20,052,999 XP from Vard (Energy of Repose 10,405). ");
	
	parser->processLines();

	
	doTest("char exp", expHourCalc->currentExp, 584561235);
	doTest("exp gained", expHourCalc->expGained, 0);
	doTest("last exp packet", expHourCalc->lastExpPacket, 20052999);
	doTest("char level", expHourCalc->level, 65);
	doTest("repose consumed", expHourCalc->reposeExp, 10405);

	//================================================================================

	header("Soul Healing / EXP loss on death");

	expHourCalc->reset();
	
	//lv 13
	//61581 xp
	//die
	//58595
	//551 zeny
	//gain 2171
	//60766 xp

	//60766
	//57510
	//59681

	//lv 43
	//21,016,061
	//die
	//20,648,891
	//18022 zeny
	//gain 244780
	//20,893,671

	cout << "lv 13 exp 61851" << endl;

	expHourCalc->level = 13;
	expHourCalc->currentExp = 61851;

	appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");

	parser->processLines();

	doTest("Died to a monster, most likely XP lost, needExpUpdate is true", expHourCalc->needExpUpdate, true);
	doTest("needApUpdate is false unless there was no XP loss", expHourCalc->needApUpdate, false);

	appendFile("temp.txt", "2013.07.04 18:15:04 : You spent 551 Kinah.");
	appendFile("temp.txt", "2013.07.04 18:15:04 : You have gained 2,171 XP. ");
	appendFile("temp.txt", "2013.07.04 18:15:04 : You received Soul Healing. ");

	parser->processLines();

	doTest("exp change:", expHourCalc->lastExpPacket, -1085);
	doTest("exp after:", expHourCalc->currentExp, 60766);
	doTest("zeny spent:", expHourCalc->cashSpent, 551);
	doTest("last zeny transaction:", expHourCalc->lastCashTransaction, -551);
	doTest("Soul healing done, needExpUpdate is false", expHourCalc->needExpUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);
	doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 1085 + 2171);

	expHourCalc->reset();

	cout << "lv 43 exp 21016061" << endl;

	expHourCalc->level = 43;
	expHourCalc->currentExp = 21016061;

	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You spent 18,022 Kinah. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You have gained 244,780 XP. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You received Soul Healing.");

	parser->processLines();

	doTest("exp change:", expHourCalc->lastExpPacket, -122390);
	doTest("exp gained so far:", expHourCalc->expGained, -122390);
	doTest("exp after:", expHourCalc->currentExp, 20893671);
	doTest("zeny spent:", expHourCalc->cashSpent, 18022);
	doTest("last zeny transaction:", expHourCalc->lastCashTransaction, -18022);

	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You spent 18,022 Kinah. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You have gained 244,780 XP. ");
	appendFile("temp.txt", "2013.07.04 18:40:23 : You received Soul Healing.");

	parser->processLines();

	doTest("expLostToDeaths after 2 deaths", expHourCalc->expLostToDeaths, (244780 + 122390) * 2);
	doTest("exp gained so far:", expHourCalc->expGained, -244780);
	doTest("currentExp:", expHourCalc->currentExp, 20893671 - 122390);

	//================================================================================

	header("1 zeny soul healing -> PKed");

	expHourCalc->reset();

	expHourCalc->level = 43;
	expHourCalc->currentExp = 21016061;

	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");
	appendFile("temp.txt","2013.07.05 00:54:59 : Saamn recovered 183 MP due to the effect of Strong Instant Recovery. ");
	appendFile("temp.txt","2013.07.05 00:54:59 : You have resurrected. ");
	appendFile("temp.txt","2013.07.05 00:55:02 : [3.LFG] [charname:ImSoBucci;1.0000 0.6941 0.6941]: [cmd:0cWaGV/kjHuy7eO6sQkkLIOFT2cFnzucw1Y29SlJmwZFUYOZnylZ5HCClET+4/tCGl2bZjvYqe8X4QPegOqKKQ==]BTHM LF DPS,TANK,HEALS ");
	appendFile("temp.txt","2013.07.05 00:55:04 : Demonjon restored 1,940 HP. ");
	appendFile("temp.txt","2013.07.05 00:55:04 : Demonjon restored 357 MP. ");
	appendFile("temp.txt","2013.07.05 00:55:09 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.07.05 00:55:09 : You received Soul Healing. ");
	appendFile("temp.txt","2013.07.05 00:55:11 : The weapon has been changed. ");

	parser->processLines();

	doTest("PK soul healing no exp loss check:", expHourCalc->currentExp, 21016061);

	//================================================================================

	header("Clear needExpUpdate if no XP to recover");

	expHourCalc->reset();
	expHourCalc->level = 44;
	expHourCalc->currentExp = 10000000;
	expHourCalc->expGained = 480752;

	appendFile("temp.txt","2013.07.15 18:24:31 : You can see again ");
	appendFile("temp.txt","2013.07.15 18:24:31 : You have died. ");
	appendFile("temp.txt","2013.07.15 16:42:31 : You have resurrected. ");
	appendFile("temp.txt","2013.07.13 17:11:07 : You do not have any XP to recover. ");

	doTest("needExpUpdate", expHourCalc->needExpUpdate, false);
	doTest("needApUpdate", expHourCalc->needApUpdate, false);

	//================================================================================

	header("Manual exp update - pve death");

	expHourCalc->reset();
	expHourCalc->level = 44;
	expHourCalc->currentExp = 10000000;
	expHourCalc->expGained = 480752;

	appendFile("temp.txt","2013.06.27 20:21:33 : You cannot do that while you are in combat.  ");
	appendFile("temp.txt","2013.06.27 20:21:33 : You have died.  ");
	appendFile("temp.txt","2013.06.27 20:21:49 : You have resurrected.  ");
	appendFile("temp.txt","2013.06.27 20:21:49 : You cannot attack the enemy faction in this region.  ");
	appendFile("temp.txt","2013.06.27 20:22:00 : Suder inflicted 4,192 damage on Training Dummy by using Ritual Push I.  ");
	
	parser->processLines();	

	expHourCalc->updateExp(10000000 - 380752);
	parser->processLines();	

	doTest("currentExp", expHourCalc->currentExp, 10000000 - 380752);
	doTest("expGained", expHourCalc->expGained, 100000);
	doTest("lastExpPacket", expHourCalc->lastExpPacket, -380752);
	doTest("needExpUpdate", expHourCalc->needExpUpdate, false);
	doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 380752);

	appendFile("temp.txt","2013.06.27 20:22:02 : You spent 28,259 Kinah.  ");
	appendFile("temp.txt","2013.06.27 20:22:02 : You have gained 719,902 XP.  ");
	appendFile("temp.txt","2013.06.27 20:22:02 : You received Soul Healing.  ");

	parser->processLines();

	doTest("soul heal after manual exp update: currentExp", expHourCalc->currentExp, 10000000 - 380752 + 719902);
	doTest("needExpUpdate is false", expHourCalc->needExpUpdate, false);
	doTest("needApUpdate is false", expHourCalc->needApUpdate, false);
	doTest("lastCashTransaction", expHourCalc->lastCashTransaction, -28259);
	doTest("cashSpent", expHourCalc->cashSpent, 28259);
	doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 380752);

	

	//================================================================================

	header("Abyss Rank");

	expHourCalc->currentAp = 1000;

	doTest("9 kyu test", expHourCalc->getAbyssRankName(), "9 kyu");

	expHourCalc->currentAp = 120000;

	doTest("2 kyu test", expHourCalc->getAbyssRankName(), "2 kyu");

	expHourCalc->currentAp = 200000;

	doTest("200000 AP test", expHourCalc->getAbyssRankName(), "???");

	expHourCalc->currentAp = 2000000000;

	doTest("2 billion AP test", expHourCalc->getAbyssRankName(), "???");

	//================================================================================

	header("AP Spending");

	expHourCalc->reset();
	expHourCalc->currentAp = 95000;
	expHourCalc->apGained = 95000;
	expHourCalc->lastApPacket = 95000;

	appendFile("temp.txt","2013.07.03 18:15:39 : Your Abyss Rank has changed to Soldier, Rank 7. ");
	appendFile("temp.txt","2013.07.03 18:15:39 : You used 89,775 Abyss Points. ");
	appendFile("temp.txt","2013.07.03 18:15:40 : [3.LFG] [charname:Vladarina;1.0000 0.6941 0.6941]: Asmos, we expect a LOT of elyos to attack [pos:Pradeth;600060000 2676.0 2720.2 0.0 0] tonight. I need everybody (even level 50s) I can get inside of that fort EARLY, before 11 pm est vuln (5 hours). Bind  ");
	appendFile("temp.txt","2013.07.03 18:15:40 : You have purchased [item:140000816;ver4;;;;]. ");

	parser->processLines();

	doTest("AP spent ", expHourCalc->apSpent, 89775);
	doTest("AP after purchase", expHourCalc->currentAp, 5225);
	doTest("AP gained after purchase", expHourCalc->apGained, 5225);		
	doTest("last AP Packet", expHourCalc->lastApPacket, -89775);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);

	//================================================================================


	header("Got PKed, need to ask for manual AP update");

	expHourCalc->reset();
	expHourCalc->currentAp = 100000;

	appendFile("temp.txt","2013.07.05 16:15:18 : Tip: Elyos and Asmodians cannot fight one another in a neutral zone.");
	appendFile("temp.txt","2013.07.05 16:15:18 : You may be unable to use certain skills or items in this area. ");
	appendFile("temp.txt","2013.07.05 16:15:18 : A survey has arrived. Click the icon to open the survey window. ");
	appendFile("temp.txt","2013.07.05 16:15:20 : You have joined Standard Server. ");
	appendFile("temp.txt","2013.07.07 00:56:26 : You are no longer silenced.  ");
	appendFile("temp.txt","2013.07.07 00:56:26 : Your movement speed is restored to normal.  ");
	appendFile("temp.txt","2013.07.07 00:56:26 : Your attack speed is restored to normal.  ");
	appendFile("temp.txt","2013.07.07 00:56:26 : You were killed by Thomasbangalter's attack.  ");
	appendFile("temp.txt","2013.07.07 00:56:28 : Noble Energy inflicted 684 damage on Thomasbangalter by using Noble Energy IV.  ");
	appendFile("temp.txt","2013.07.07 00:56:28 : Thomasbangalter inflicted 733 damage on Devios by using Illusion Storm VII.  ");

	parser->processLines();

	doTest("I'm on Standard Server", expHourCalc->getCurrentServer(), "Standard");
	doTest("Got PKed in standard server, need ap update yes", expHourCalc->needApUpdate, true);
	doTest("needExpUpdate needs to be false", expHourCalc->needExpUpdate, false);

	expHourCalc->updateAp(95000);
	appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. ");

	parser->processLines();

	doTest("already updated AP, don't apupdate again", expHourCalc->needApUpdate, false);

	appendFile("temp.txt","2013.07.07 00:56:26 : You were killed by Sogyawie's attack.  ");
	appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. ");

	parser->processLines();

	doTest("Got PKed, didn't update AP, soul healed", expHourCalc->needApUpdate, true);

	header("Got killed in structured PvP, no AP loss, don't ask for update");

	expHourCalc->reset();
	appendFile("temp.txt","2013.06.25 14:44:14 : You have item(s) left to settle at the Broker. ");
	appendFile("temp.txt","2013.06.25 14:44:16 : You have joined the group. ");
	appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion region channel. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion trade channel. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the LFG Channel. ");
	appendFile("temp.txt","2013.06.25 14:44:23 : Nekoh-IS has joined your group. ");
	appendFile("temp.txt","2013.06.25 14:44:24 : You have joined the Templar Channel. ");
	appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack.");

	parser->processLines();

	doTest("I'm on Instance Server", expHourCalc->getCurrentServer(), "Instance");
	doTest("needApUpdate should be false", expHourCalc->needApUpdate, false);

	header("Got killed in by mobster in structured PvP, manual EXP enter, no EXP or AP loss, don't ask for AP update");

	expHourCalc->reset();
	expHourCalc->level = 60;
	expHourCalc->currentExp = 1234567;
	appendFile("temp.txt","2013.06.25 14:44:14 : You have item(s) left to settle at the Broker. ");
	appendFile("temp.txt","2013.06.25 14:44:16 : You have joined the group. ");
	appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion region channel. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the Terath Dredgion trade channel. ");
	appendFile("temp.txt","2013.06.25 14:44:21 : You have joined the LFG Channel. ");
	appendFile("temp.txt","2013.06.25 14:44:23 : Nekoh-IS has joined your group. ");
	appendFile("temp.txt","2013.06.25 14:44:24 : You have joined the Templar Channel. ");
	appendFile("temp.txt","2013.06.27 19:04:58 : You have died. ");

	parser->processLines();
	expHourCalc->updateExp(1234567);
	parser->processLines();
	
	doTest("needApUpdate should be false", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);
	doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 0);
	doTest("apLostToPk", expHourCalc->apLostToPk, 0);

	appendFile("temp.txt","2013.07.05 16:15:20 : You have joined Standard Server. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");
	
	parser->processLines();

	header("Back to Standard Server, attacked by enemy faction player, finished blow from monster"); 
	doTest("Don't know whether XP was lost or not - needExpUpdate is true", expHourCalc->needExpUpdate, true);

	appendFile("temp.txt","2013.06.27 23:03:19 : You do not have much flight time left. Please land on a secure place. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : Pashid Offense Elite Fighter is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Fighter used Conqueror's Passion. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : Pashid Offense Elite Protector is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Protector used Conqueror's Passion. ");
	appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. ");
	appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. ");
	appendFile("temp.txt","2013.06.27 23:03:20 : Pashid Offense Elite Archer is in the boost Physical Def,Magical Defense state because Pashid Offense Elite Archer used Conqueror's Passion. ");
	appendFile("temp.txt","2013.06.27 23:03:24 : [charname:Gwc;0.6118 0.9059 0.8627]: gub ");
	appendFile("temp.txt","2013.06.27 23:03:26 : You have resurrected. ");

	appendFile("temp.txt","2013.06.27 23:03:50 : [charname:Mystfang;0.6118 0.9059 0.8627]: omg ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. ");

	parser->processLines();

	doTest("1 zeny soul healing means u lost AP", expHourCalc->needApUpdate, true);
	doTest("No EXP loss when you lost AP", expHourCalc->needExpUpdate, false);
	doTest("Soul healing done, needExpUpdate is false", expHourCalc->needExpUpdate, false);

	expHourCalc->currentExp = 100000;
	expHourCalc->currentAp = 1000000;

	header("Manual XP update, EXP unchanged (no exp loss) = possible AP loss");

	appendFile("temp.txt","2013.06.27 23:03:19 : You are no longer bleeding. ");
	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");

	parser->processLines();

	expHourCalc->updateExp(100000);
	parser->processLines();	

	doTest("needApUpdate", expHourCalc->needApUpdate, true);
	doTest("clear needExpUpdate", expHourCalc->needExpUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);
	
	expHourCalc->updateAp(999000);
	parser->processLines();	

	doTest("After manual AP update, needExpUpdate false", expHourCalc->needExpUpdate, false);
	doTest("After manual AP update, needApUpdate false", expHourCalc->needApUpdate, false);
	doTest("current exp", expHourCalc->currentExp, 100000);
	doTest("current ap", expHourCalc->currentAp, 999000);
	doTest("last exp packet", expHourCalc->lastExpPacket, 0);
	doTest("last ap packet", expHourCalc->lastApPacket, -1000);
	doTest("expLostToDeaths", expHourCalc->expLostToDeaths, 0);
	doTest("apLostToPk", expHourCalc->apLostToPk, 1000);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);

	appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. ");
	parser->processLines();
	
	doTest("After manual AP update, soul healed, don't ask for AP update again", expHourCalc->needApUpdate, false);

	//================================================================================

	header("Promopt for AP update due to AP loss on death");

	expHourCalc->reset();
	expHourCalc->currentAp = 95000;
	expHourCalc->apGained = 95000;
	expHourCalc->lastApPacket = 1234;

	appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack.");

	parser->processLines();

	cout << endl << "Invalid update" << endl;

	expHourCalc->updateAp(95001);
	parser->processLines();	
	doTest("currentAp after invalid update", expHourCalc->currentAp, 95000);
	doTest("apGained after invalid update", expHourCalc->apGained, 95000);		
	doTest("lastApPacket after invalid update", expHourCalc->lastApPacket, 1234);
	doTest("apLostToPk after invalid update", expHourCalc->apLostToPk, 0);
	doTest("Still need ap update", expHourCalc->needApUpdate, true);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false);
	doTest("apLostToPk", expHourCalc->apLostToPk, 0);

	cout << endl << "Valid update" << endl;

	expHourCalc->updateAp(94500);
	parser->processLines();	
	doTest("currentAp after getting PKed", expHourCalc->currentAp, 94500);
	doTest("apGained after getting PKed", expHourCalc->apGained, 94500);		
	doTest("lastApPacket after getting PKed", expHourCalc->lastApPacket, -500);
	doTest("apLostToPk after getting PKed", expHourCalc->apLostToPk, 500);
	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);	
	doTest("apLostToPk", expHourCalc->apLostToPk, 500);

	header("Double deaths");

	appendFile("temp.txt","2013.06.27 17:08:23 : You have gained 3,421,093 XP from Lumiden. ");
	appendFile("temp.txt","2013.06.27 17:08:23 : You have gained 402 Abyss Points. ");
	appendFile("temp.txt","2013.06.27 17:08:23 : You can receive the weekly quest again at 9 in the morning on Wednesday. ");
	appendFile("temp.txt","2013.09.05 20:35:58 : You were killed by SteveForansi's attack.");
	parser->processLines();

	expHourCalc->updateAp(93602);
	parser->processLines();
	
	doTest("currentAp after getting PKed for second time", expHourCalc->currentAp, 93602);
	doTest("apGained after getting PKed for second time", expHourCalc->apGained, 93602);
	doTest("lastApPacket after getting PKed  for second time", expHourCalc->lastApPacket, -1300);
	doTest("apLostToPk", expHourCalc->apLostToPk, 1800);
	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);	


	cout << endl << "Reject inputs that exceed currentAP + apLostToPk" << endl;

	appendFile("temp.txt","2013.09.05 20:35:58 : You were killed by V****a's attack.");
	parser->processLines();

	expHourCalc->updateAp(95403);
	parser->processLines();

	doTest("currentAp", expHourCalc->currentAp, 93602);
	doTest("apGained ", expHourCalc->apGained, 93602);	
	doTest("lastApPacket", expHourCalc->lastApPacket, -1300);
	doTest("apLostToPk", expHourCalc->apLostToPk, 1800);
	doTest("Still need ap update", expHourCalc->needApUpdate, true);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, false);	

	expHourCalc->updateAp(95402);
	parser->processLines();

	cout << endl << "Allow manual updates up to currentAP + apLostToPk" << endl;

	doTest("currentAp", expHourCalc->currentAp, 95402);
	doTest("apGained ", expHourCalc->apGained, 95402);
	doTest("lastApPacket", expHourCalc->lastApPacket, 1800);
	doTest("apLostToPk", expHourCalc->apLostToPk, 0);
	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is true", expHourCalc->lastTickHasChanges, true);	


	//================================================================================

	header("AP not entered during startup");

	expHourCalc->reset();
	expHourCalc->level = 60;
	expHourCalc->currentExp = 50000000;
	expHourCalc->currentAp = -1;
	expHourCalc->apGained = 95000;
	expHourCalc->lastApPacket = 1234;

	appendFile("temp.txt","2013.06.27 19:04:58 : You were killed by Mrplatino's attack.");

	parser->processLines();

	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false);
	

	cout << endl << "Attacked by player, finishing blow by monster, soul healing" << endl;

	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");

	appendFile("temp.txt","2013.06.27 23:03:52 : You spent 1 Kinah. ");
	appendFile("temp.txt","2013.06.27 23:03:52 : You received Soul Healing. ");

	parser->processLines();

	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false);

	cout << endl << "Attacked by player, finishing blow by monster, manual exp update" << endl;

	appendFile("temp.txt","2013.06.27 23:03:19 : You have died. ");
	parser->processLines();

	expHourCalc->updateExp(50000000);
	parser->processLines();

	doTest("don't need exp update", expHourCalc->needExpUpdate, false);
	doTest("Still need ap update", expHourCalc->needApUpdate, false);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, true);


	//================================================================================

	header("Blood Marks and AP Relics");

	expHourCalc->reset();

	expHourCalc->currentAp = 10000;
	expHourCalc->apGained = 1000;
	
	appendFile("temp.txt","2013.07.23 12:32:19 : You have acquired [item:186000066;ver4;;;;]. ");
	appendFile("temp.txt","2013.07.23 12:32:19 : You have acquired 2 [item:162000120;ver4;;;;](s). ");
	
	parser->processLines();

	doTest("currentAP after lesser icon", expHourCalc->currentAp, 10000);
	doTest("apGained after lesser icon", expHourCalc->apGained, 1000);
	doTest("relicAp after lesser icon", expHourCalc->relicAp, 315);

	appendFile("temp.txt","2013.07.22 17:19:53 : Quest updated: [Daily] Sweeping Away the Elyos ");
	appendFile("temp.txt","2013.07.22 17:19:54 : You have acquired 12 [item:186000236;ver4;;;;]s and stored them in your special cube. ");
	appendFile("temp.txt","2013.07.22 17:19:54 : You have gained 3,446,516 XP from Hrund. ");
	appendFile("temp.txt","2013.07.22 17:19:54 : You can receive the weekly quest again at 9 in the morning on Wednesday. ");
	appendFile("temp.txt","2013.07.22 17:19:54 : Quest complete: [Daily] Sweeping Away the Elyos ");

	parser->processLines();

	doTest("relicAp after 12 blood mark", expHourCalc->relicAp, 6413);

	//================================================================================

	header("NPC Sales");
	//isNpcSales
	appendFile("temp.txt","2013.11.07 03:15:58 : Sales complete.");
	appendFile("temp.txt","2013.11.07 03:15:58 : You have earned 288 Kinah.");	
	
	parser->processLines();

	doTest("cashGained", expHourCalc->cashGained, 288);
	doTest("cashSpent", expHourCalc->cashSpent, 0);
	doTest("lastCashTransaction", expHourCalc->lastCashTransaction, 288);
	doTest("getNetCashFlow()", expHourCalc->getNetCashFlow(), 288);
	doTest("npcSales", expHourCalc->npcSales, 288);

	appendFile("temp.txt", "2013.09.03 22:39:32 : You sold the item. ");	
	appendFile("temp.txt", "2013.09.03 22:39:32 : You have gained 376,068 Abyss Points. ");	
	parser->processLines();

	doTest("currentAp", expHourCalc->currentAp, 10000 + 376068);
	doTest("apGained", expHourCalc->apGained, 1000 + 376068);
	doTest("relicAp", expHourCalc->relicAp, 6413 - 376068);

	header("Not NPC Sales");

	appendFile("temp.txt", "2013.11.05 13:04:54 : You have earned 11,550,000 Kinah.");
	parser->processLines();

	doTest("cashGained", expHourCalc->cashGained, 11550000 + 288);
	doTest("cashSpent", expHourCalc->cashSpent, 0);
	doTest("lastCashTransaction", expHourCalc->lastCashTransaction, 11550000);
	doTest("getNetCashFlow()", expHourCalc->getNetCashFlow(), 11550288);
	doTest("npcSales", expHourCalc->npcSales, 288);

	appendFile("temp.txt", "2013.11.05 13:43:19 : Captain Anusa is under attack. ");
	appendFile("temp.txt", "2013.11.05 13:43:20 : You have gained 5,674 Abyss Points. ");
	appendFile("temp.txt", "2013.11.05 13:43:20 : Quest updated: [Service/Group] Unending Assault ");
	parser->processLines();

	doTest("currentAp", expHourCalc->currentAp, 10000 + 376068 + 5674);
	doTest("apGained", expHourCalc->apGained, 1000 + 376068 + 5674);
	doTest("relicAp", expHourCalc->relicAp, 6413 - 376068);



	//================================================================================

	header("Join Channel");

	appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the Poeta region channel. ");
	appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the Poeta trade channel. ");
	appendFile("temp.txt","2013.07.24 15:28:52 : You have joined the LFG Channel. ");
	appendFile("temp.txt","2013.07.24 15:28:55 : You have joined the Assassin Channel. ");
	appendFile("temp.txt","2013.07.24 15:28:55 : You have joined the Ranger Channel. ");
	appendFile("temp.txt","2013.06.25 14:44:16 : You have joined Instance Server.");

	parser->processLines();

	doTest("currentServer", expHourCalc->currentServer, INSTANCE_SERVER);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false);

	//================================================================================

	header("Do not recognize user chat as commands");

	expHourCalc->reset();

	expHourCalc->level = 43;
	expHourCalc->currentExp = 21016061;
	expHourCalc->lastExpPacket = 10000;
	expHourCalc->lastCashTransaction = 62351;

	appendFile("temp.txt","2013.07.24 15:24:51 : [3.LFG] [charname:Eikwel;1.0000 0.6941 0.6941]: blah blah blah : You received Soul Healing.");

	parser->processLines();

	doTest("Soul healing from chat", expHourCalc->currentExp, 21016061);
	doTest("Soul healing from chat", expHourCalc->lastExpPacket, 10000);
	doTest("lastTickHasChanges is false", expHourCalc->lastTickHasChanges, false);

	//================================================================================
	printSummary();
	delete(parser);
	remove("temp.txt");

	getchar();
	return 0;
}
 void copyFile(const boost::filesystem::path &src, const boost::filesystem::path &dst)
 {
     const unistd::Descriptor dstFd(unistd::open(dst, O_WRONLY | O_CREAT | O_TRUNC));
     appendFile(src, dstFd.get());
 }
Beispiel #24
0
void FormData::appendKeyValuePairItems(const FormDataList& list, const WTF::TextEncoding& encoding, bool isMultiPartForm, Document* document, EncodingType encodingType)
{
    if (isMultiPartForm)
        m_boundary = FormDataBuilder::generateUniqueBoundaryString();

    Vector<char> encodedData;

    const Vector<FormDataList::Item>& items = list.items();
    size_t formDataListSize = items.size();
    ASSERT(!(formDataListSize % 2));
    for (size_t i = 0; i < formDataListSize; i += 2) {
        const FormDataList::Item& key = items[i];
        const FormDataList::Item& value = items[i + 1];
        if (isMultiPartForm) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());

            // If the current type is blob, then we also need to include the filename
            if (value.blob()) {
                String name;
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // For file blob, use the filename (or relative path if it is present) as the name.
                    name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();

                    // If a filename is passed in FormData.append(), use it instead of the file blob's name.
                    if (!value.filename().isNull())
                        name = value.filename();
                } else {
                    // For non-file blob, use the filename if it is passed in FormData.append().
                    if (!value.filename().isNull())
                        name = value.filename();
                    else
                        name = "blob";
                }

                // We have to include the filename=".." part in the header, even if the filename is empty
                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);

                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
                String contentType;
                if (value.blob()->type().isEmpty())
                    contentType = "application/octet-stream";
                else
                    contentType = value.blob()->type();
                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
            }

            FormDataBuilder::finishMultiPartHeader(header);

            // Append body
            appendData(header.data(), header.size());
            if (value.blob()) {
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // Do not add the file if the path is empty.
                    if (!file->path().isEmpty())
                        appendFile(file->path());
                    if (!file->fileSystemURL().isEmpty())
                        appendURL(file->fileSystemURL());
                }
                else
                    appendBlob(value.blob()->url());
            } else
                appendData(value.data().data(), value.data().length());
            appendData("\r\n", 2);
        } else {
            // Omit the name "isindex" if it's the first form data element.
            // FIXME: Why is this a good rule? Is this obsolete now?
            if (encodedData.isEmpty() && key.data() == "isindex")
                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
            else
                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
        }
    }

    if (isMultiPartForm)
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);

    appendData(encodedData.data(), encodedData.size());
}
 void concatenate(const std::vector<boost::filesystem::path> &srcs, const boost::filesystem::path &dst)
 {
     const unistd::Descriptor dstFd(unistd::open(dst, O_WRONLY | O_CREAT | O_TRUNC));
     for (const boost::filesystem::path &src: srcs)
         appendFile(src, dstFd.get());
 }
Beispiel #26
0
static bool
prepareInternal(const char *stmt)
{
    short i, nc, coltype, colscale, nullable, namelen;
    unsigned long colprec;
    bool blobpresent = false;

    checkConnect();
    everything_null = true;
    if(isnullstring(stmt))
	errorPrint("2null SQL statement");
    stmt_text = stmt;
    debugStatement();

    /* look for delete with no where clause */
    skipWhite(&stmt);
    if(!strncmp(stmt, "delete", 6) || !strncmp(stmt, "update", 6))
	/* delete or update */
	if(!strstr(stmt, "where") && !strstr(stmt, "WHERE")) {
	    showStatement();
	    setError(MSG_DBNoWhere);
	    return false;
	}

    rv_numRets = 0;
    memset(rv_type, 0, NUMRETS);
    memset(rv_nullable, 0, NUMRETS);
    rv_lastNrows = 0;

    if(openfirst)
	rc = SQLExecDirect(hstmt, (char *)stmt, SQL_NTS);
    else
	rc = SQLPrepare(hstmt, (char *)stmt, SQL_NTS);
    if(errorTrap(0))
	return false;

    /* gather column headings and types */
    rc = SQLNumResultCols(hstmt, &nc);
    if(errorTrap(0))
	return false;

    if(nc > NUMRETS) {
	showStatement();
	errorPrint("2cannot select more than %d values", NUMRETS);
    }

    for(i = 0; i < nc; ++i) {
	rc = SQLDescribeCol(hstmt, (USHORT) (i + 1),
	   rv_name[i], COLNAMELEN, &namelen,
	   &coltype, &colprec, &colscale, &nullable);
	if(errorTrap("01004"))
	    return false;

/*********************************************************************
The following is an Informix kludge,
because intervals are not mapped back into SQL_TIME,
as they should be.  Don't create any varchar(24,0) columns.
Also, ODBC hasn't got any money type.
Under informix, it comes back as decimal.
We never use decimal columns, so we can turn decimal back into money.
However, some aggregate expressions also come back as decimal.
Count(*) becomes decimal(15,0).  So be careful.
*********************************************************************/

	if(current_driver == DRIVER_INFORMIX) {
	    if(coltype == SQL_VARCHAR && colprec == 24 && colscale == 0)
		coltype = SQL_TIME;
#if 0
	    if(coltype == SQL_DECIMAL && (colprec != 15 || colscale != 0))
		coltype = SQL_MONEY;
#endif
	}

	if(current_driver == DRIVER_SQLITE) {
/* Every column looks like a text blob, but it is really a string. */
	    coltype = SQL_CHAR;
	    colprec = STRINGLEN;
	}

	rv_nullable[i] = (nullable != SQL_NO_NULLS);

	switch (coltype) {
	case SQL_BIT:
	case SQL_TINYINT:
	case SQL_SMALLINT:
	case SQL_INTEGER:
	case SQL_BIGINT:
	case SQL_NUMERIC:
	    rv_type[i] = 'N';
	    break;

	case SQL_TIMESTAMP:
/* I don't know what to do with these; just make them strings. */
	    rv_type[i] = 'S';
	    break;

	case SQL_DATE:
	    rv_type[i] = 'D';
	    break;

	case SQL_DOUBLE:
	case SQL_FLOAT:
	case SQL_DECIMAL:
	case SQL_REAL:
	    rv_type[i] = 'F';
	    break;

	case SQL_TIME:
	    rv_type[i] = 'I';
	    break;

	case SQL_CHAR:
	case SQL_VARCHAR:
	    rv_type[i] = 'S';
	    if(colprec == 1)
		rv_type[i] = 'C';
	    if(colprec > STRINGLEN && sql_debug) {
		appendFile(sql_debuglog, "column %s exceeds %d characters",
		   rv_name[i], STRINGLEN);
	    }
	    break;

	case SQL_LONGVARCHAR:
	case SQL_BINARY:
	case SQL_VARBINARY:
	case SQL_LONGVARBINARY:
	    if(blobpresent) {
		showStatement();
		errorPrint("2Statement selects more than one blob column");
	    }
	    blobpresent = true;
	    rv_type[i] = (coltype == SQL_LONGVARCHAR ? 'T' : 'B');
	    break;

	case SQL_MONEY:
	    rv_type[i] = 'M';
	    break;

	default:
	    errorPrint("@Unknown sql datatype %d", coltype);
	}			/* switch on type */
    }				/* loop over returns */

    rv_numRets = nc;
    return true;
}				/* prepareInternal */
Beispiel #27
0
void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document, EncodingType encodingType)
{
    if (isMultiPartForm)
        m_boundary = FormDataBuilder::generateUniqueBoundaryString();

    Vector<char> encodedData;

    const Vector<FormDataList::Item>& items = list.items();
    size_t formDataListSize = items.size();
    ASSERT(!(formDataListSize % 2));
    for (size_t i = 0; i < formDataListSize; i += 2) {
        const FormDataList::Item& key = items[i];
        const FormDataList::Item& value = items[i + 1];
        if (isMultiPartForm) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());

            bool shouldGenerateFile = false;

            // If the current type is blob, then we also need to include the filename
            if (value.blob()) {
                String name;
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    name = file->name();
                    // Let the application specify a filename if it's going to generate a replacement file for the upload.
                    const String& path = file->path();
                    if (!path.isEmpty()) {
                        if (Page* page = document->page()) {
                            String generatedFileName;
                            shouldGenerateFile = page->chrome().client().shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
                            if (shouldGenerateFile)
                                name = generatedFileName;
                        }
                    }

                    // If a filename is passed in FormData.append(), use it instead of the file blob's name.
                    if (!value.filename().isNull())
                        name = value.filename();
                } else {
                    // For non-file blob, use the filename if it is passed in FormData.append().
                    if (!value.filename().isNull())
                        name = value.filename();
                    else
                        name = "blob";
                }

                // We have to include the filename=".." part in the header, even if the filename is empty
                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);

                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
                String contentType = value.blob()->type();
                if (contentType.isEmpty())
                    contentType = "application/octet-stream";
                ASSERT(Blob::isNormalizedContentType(contentType));
                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.ascii());
            }

            FormDataBuilder::finishMultiPartHeader(header);

            // Append body
            appendData(header.data(), header.size());
            if (value.blob()) {
                if (value.blob()->isFile()) {
                    File* file = toFile(value.blob());
                    // Do not add the file if the path is empty.
                    if (!file->path().isEmpty())
                        appendFile(file->path(), shouldGenerateFile);
                }
                else
                    appendBlob(value.blob()->url());
            } else
                appendData(value.data().data(), value.data().length());
            appendData("\r\n", 2);
        } else {
            // Omit the name "isindex" if it's the first form data element.
            // FIXME: Why is this a good rule? Is this obsolete now?
            if (encodedData.isEmpty() && key.data() == "isindex")
                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
            else
                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
        }
    }

    if (isMultiPartForm)
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);

    appendData(encodedData.data(), encodedData.size());
}
Beispiel #28
0
void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
{
    if (isMultiPartForm)
        m_boundary = FormDataBuilder::generateUniqueBoundaryString();

    Vector<char> encodedData;

    const Vector<FormDataList::Item>& items = list.items();
    size_t formDataListSize = items.size();
    ASSERT(!(formDataListSize % 2));
    for (size_t i = 0; i < formDataListSize; i += 2) {
        const FormDataList::Item& key = items[i];
        const FormDataList::Item& value = items[i + 1];
        if (isMultiPartForm) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());

            bool shouldGenerateFile = false;

            // If the current type is blob, then we also need to include the filename
            if (value.blob()) {
                String name;
                if (value.blob()->isFile()) {
                    // For file blob, use the filename (or relative path if it is present) as the name.
                    File* file = static_cast<File*>(value.blob());
#if ENABLE(DIRECTORY_UPLOAD)                
                    name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();
#else
                    name = file->name();
#endif                    

                    // Let the application specify a filename if it's going to generate a replacement file for the upload.
                    if (Page* page = document->page()) {
                        String generatedFileName;
                        shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(file->path(), generatedFileName);
                        if (shouldGenerateFile)
                            name = generatedFileName;
                    }
                } else {
                    // For non-file blob, use the identifier part of the URL as the name.
                    name = "Blob" + BlobURL::getIdentifier(value.blob()->url());
                    name = name.replace("-", ""); // For safety, remove '-' from the filename since some servers may not like it.
                }

                // We have to include the filename=".." part in the header, even if the filename is empty
                FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);

                // Add the content type if available, or "application/octet-stream" otherwise (RFC 1867).
                String contentType;
                if (value.blob()->type().isEmpty())
                    contentType = "application/octet-stream";
                else
                    contentType = value.blob()->type();
                FormDataBuilder::addContentTypeToMultiPartHeader(header, contentType.latin1());
            }

            FormDataBuilder::finishMultiPartHeader(header);

            // Append body
            appendData(header.data(), header.size());
            if (value.blob()) {
                if (value.blob()->isFile()) {
                    // Do not add the file if the path is empty.
                    if (!static_cast<File*>(value.blob())->path().isEmpty())
                        appendFile(static_cast<File*>(value.blob())->path(), shouldGenerateFile);
                }
#if ENABLE(BLOB)
                else
                    appendBlob(value.blob()->url());
#endif
            } else
                appendData(value.data().data(), value.data().length());
            appendData("\r\n", 2);
        } else {
            // Omit the name "isindex" if it's the first form data element.
            // FIXME: Why is this a good rule? Is this obsolete now?
            if (encodedData.isEmpty() && key.data() == "isindex")
                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
            else
                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data());
        }
    }

    if (isMultiPartForm)
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, m_boundary.data(), true);

    appendData(encodedData.data(), encodedData.size());
}