00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "cmt1.h"
00026 #include <errno.h>
00027 #ifndef _WIN32
00028 # include <stdlib.h>
00029 # include <unistd.h>
00030 # include <sys/ioctl.h>
00031 # include <fcntl.h>
00032 # include <string.h>
00033 # include <sys/param.h>
00034
00035
00036
00037
00038 # undef PATH_MAX
00039 # define PATH_MAX CMT_MAX_FILENAME_LENGTH
00040 #else
00041 # include <io.h>
00042 #endif
00043
00044 #ifndef _CRT_SECURE_NO_DEPRECATE
00045 # define _CRT_SECURE_NO_DEPRECATE
00046 # ifdef _WIN32
00047 # pragma warning(disable:4996)
00048 # endif
00049 #endif
00050
00051 #ifdef _WIN32
00052 # define FSEEK(x) _fseeki64(m_handle, x, SEEK_SET)
00053 # define FSEEK_R(x) _fseeki64(m_handle, x, SEEK_END)
00054 # define FTELL() _ftelli64(m_handle)
00055 #else
00056 # define FSEEK(x) fseeko(m_handle, x, SEEK_SET)
00057 # define FSEEK_R(x) fseeko(m_handle, x, SEEK_END)
00058 # define FTELL() ftello(m_handle)
00059 #endif
00060
00061
00062 namespace xsens {
00063
00064 #ifndef _WIN32
00065 int _wcsnicmp(const wchar_t* s1, const wchar_t* s2,int count)
00066 {
00067 for (int i = 0; i < count; ++i, ++s1, ++s2)
00068 if (*s1 == L'\0')
00069 if (*s2 == L'\0')
00070 return 0;
00071 else
00072 return -1;
00073 else
00074 if (*s2 == L'\0')
00075 return 1;
00076 else
00077 if (*s1 < *s2)
00078 return -1;
00079 else if (*s1 > *s2)
00080 return 1;
00081 return 0;
00082 }
00083 #endif
00084
00085
00086 #if defined(_DEBUG) || defined(_LOG_ALWAYS)
00087 #if !defined(_LOG_TO_DBVIEW)
00088 #ifdef _LOG_TO_STDOUT
00089 #else // !dbview && !stdout
00090 FILE* debug_log_fp = NULL;
00091 int32_t debug_log_valid = 0;
00092
00093 FILE* debug_qlog_fp = NULL;
00094 int32_t debug_qlog_valid = 0;
00095 #endif
00096 #endif
00097
00098
00099 void CMTLOG(const char *str, ...)
00100 {
00101 #ifdef _LOG_TO_STDOUT
00102 va_list ptr;
00103 va_start(ptr,str);
00104 vprintf(str,ptr);
00105 #else
00106 #ifdef _LOG_TO_DBVIEW
00107 char buf[2048];
00108
00109 va_list ptr;
00110 va_start(ptr,str);
00111 vsprintf(buf,str,ptr);
00112
00113 OutputDebugString(buf);
00114 #else
00115 if (debug_log_valid == 0)
00116 {
00117 fopen_s(&debug_log_fp,"debug_log_cmt.log","w");
00118 if (debug_log_fp != NULL)
00119 debug_log_valid = 1;
00120 else
00121 debug_log_valid = -1;
00122 }
00123 if (debug_log_valid == 1)
00124 {
00125 char buf[2048];
00126
00127 va_list ptr;
00128 va_start(ptr,str);
00129 int32_t sz = vsprintf_s(buf,str,ptr);
00130
00131 uint32_t nw = getTimeOfDay();
00132 fprintf(debug_log_fp,"%5u.%03u %s",nw/1000,nw%1000,buf);
00133
00134 fflush(debug_log_fp);
00135 }
00136 #endif
00137 #endif
00138 }
00139 #endif
00140
00141
00142 #ifdef _LOG_CMT1
00143 #define CMT1LOG CMTLOG
00144 #else
00145 #define CMT1LOG(...)
00146 #endif
00147
00148
00149
00150
00151
00152
00153
00154 Cmt1s::Cmt1s() :
00155 m_onBytesReceived(NULL)
00156 {
00157 m_port = 0;
00158 m_isOpen = false;
00159 m_lastResult = XRV_OK;
00160 m_timeout = CMT1_DEFAULT_TIMEOUT;
00161 m_endTime = 0;
00162 m_baudrate = 0;
00163
00164 #ifdef _LOG_RX_TX
00165 rx_log = NULL;
00166 tx_log = NULL;
00167 #endif
00168 }
00169
00170
00171
00172 Cmt1s::~Cmt1s()
00173 {
00174 close();
00175 }
00176
00177
00178
00179 XsensResultValue Cmt1s::close (void)
00180 {
00181 #ifdef _LOG_RX_TX
00182 if (rx_log != NULL)
00183 fclose(rx_log);
00184 if (tx_log != NULL)
00185 fclose(tx_log);
00186 rx_log = NULL;
00187 tx_log = NULL;
00188 #endif
00189 if (!m_isOpen)
00190 return m_lastResult = XRV_NOPORTOPEN;
00191
00192 #ifdef _WIN32
00193 ::FlushFileBuffers(m_handle);
00194
00195
00196 COMMTIMEOUTS cto;
00197 ::GetCommTimeouts(m_handle,&cto);
00198 cto.ReadIntervalTimeout = MAXDWORD;
00199 cto.ReadTotalTimeoutConstant = 0;
00200 cto.ReadTotalTimeoutMultiplier = 0;
00201 ::SetCommTimeouts(m_handle,&cto);
00202 char buffer[1024];
00203 uint32_t length;
00204 do {
00205 ::ReadFile(m_handle, buffer, 1024, &length, NULL);
00206 } while (length > 0);
00207 BOOL murf = ::CloseHandle(m_handle);
00208 #else
00209 ::close(m_handle);
00210 #endif
00211 m_isOpen = false;
00212 m_endTime = 0;
00213
00214 return m_lastResult = XRV_OK;
00215 }
00216
00217
00218
00219 XsensResultValue Cmt1s::escape (const CmtControlLine mask, const CmtControlLine state)
00220 {
00221 if (!m_isOpen)
00222 return (m_lastResult = XRV_NOPORTOPEN);
00223 #ifdef _WIN32
00224 BOOL rv = 0;
00225 if (mask & CMT_CONTROL_DTR)
00226 {
00227 if (state & CMT_CONTROL_DTR)
00228 rv = EscapeCommFunction(m_handle,SETDTR);
00229 else
00230 rv = EscapeCommFunction(m_handle,CLRDTR);
00231 }
00232
00233 if (mask & CMT_CONTROL_RTS)
00234 {
00235 if (state & CMT_CONTROL_RTS)
00236 rv = EscapeCommFunction(m_handle,SETRTS);
00237 else
00238 rv = EscapeCommFunction(m_handle,CLRRTS);
00239 }
00240 if (rv)
00241 return m_lastResult = XRV_OK;
00242 else
00243 return m_lastResult = XRV_ERROR;
00244 #else
00245 bool rv = true;
00246 int32_t status;
00247 if (mask & CMT_CONTROL_DTR)
00248 {
00249 if (ioctl(m_handle, TIOCMGET, &status) == -1)
00250 {
00251 if (state & CMT_CONTROL_DTR) status |= TIOCM_DTR;
00252 else status &= ~TIOCM_DTR;
00253 rv = (ioctl(m_handle, TIOCMSET, &status) == -1);
00254 }
00255 else
00256 rv = false;
00257 }
00258 if (rv && (mask & CMT_CONTROL_RTS))
00259 {
00260 if (ioctl(m_handle, TIOCMGET, &status) == -1)
00261 {
00262 if (state & CMT_CONTROL_RTS) status |= TIOCM_RTS;
00263 else status &= ~TIOCM_RTS;
00264 rv = (ioctl(m_handle, TIOCMSET, &status) == -1);
00265 }
00266 else
00267 rv = false;
00268 }
00269 if (rv)
00270 return m_lastResult = XRV_OK;
00271 else
00272 return m_lastResult = XRV_ERROR;
00273 #endif
00274 }
00275
00276
00277
00278 XsensResultValue Cmt1s::flushData (void)
00279 {
00280 #ifdef _WIN32
00281
00282 PurgeComm(m_handle, PURGE_TXCLEAR | PURGE_RXCLEAR);
00283 #else
00284 tcflush(m_handle, TCIOFLUSH);
00285 #endif
00286 m_endTime = 0;
00287 return (m_lastResult = XRV_OK);
00288 }
00289
00290
00291
00292 XsensResultValue Cmt1s::open( const char *portName,
00293 const uint32_t baudRate,
00294 uint32_t readBufSize,
00295 uint32_t writeBufSize)
00296 {
00297 m_endTime = 0;
00298
00299 CMT1LOG("L1: Open port %s at %d baud\n", portName, baudRate);
00300
00301 if (m_isOpen)
00302 {
00303 CMT1LOG("L1: Port already open\n");
00304 return (m_lastResult = XRV_ALREADYOPEN);
00305 }
00306 m_baudrate = baudRate;
00307
00308 #ifdef _WIN32
00309 char winPortName[32];
00310
00311
00312 sprintf(winPortName, "\\\\.\\%s", portName);
00313 m_handle = CreateFile(winPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
00314 OPEN_EXISTING, 0, NULL);
00315 if (m_handle == INVALID_HANDLE_VALUE)
00316 {
00317 CMT1LOG("L1: Port cannot be opened\n");
00318 return (m_lastResult = XRV_INPUTCANNOTBEOPENED);
00319 }
00320
00321
00322 m_isOpen = true;
00323
00324
00325 GetCommState(m_handle, &m_commState);
00326
00327 m_commState.BaudRate = baudRate;
00328 m_commState.Parity = NOPARITY;
00329 m_commState.ByteSize = 8;
00330 m_commState.StopBits = TWOSTOPBITS;
00331 m_commState.fDsrSensitivity = FALSE;
00332 m_commState.fOutxCtsFlow = FALSE;
00333 m_commState.fOutxDsrFlow = FALSE;
00334 m_commState.fOutX = FALSE;
00335 m_commState.fInX = FALSE;
00336 if (!SetCommState(m_handle, (LPDCB)&m_commState)) {
00337
00338
00339 m_commState.StopBits = ONESTOPBIT;
00340 if (!SetCommState(m_handle, (LPDCB)&m_commState)) {
00341 CloseHandle(m_handle);
00342 m_handle = INVALID_HANDLE_VALUE;
00343 m_isOpen = false;
00344 return (m_lastResult = XRV_INPUTCANNOTBEOPENED);
00345 }
00346 }
00347 m_port = atoi(&portName[3]);
00348 sprintf(m_portname, "%s", portName);
00349
00350 setTimeout(m_timeout);
00351
00352
00353 EscapeCommFunction(m_handle, SETRTS);
00354
00355 EscapeCommFunction(m_handle, SETDTR);
00356 SetupComm(m_handle,readBufSize,writeBufSize);
00357
00358
00359
00360 PurgeComm(m_handle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
00361 #else // !_WIN32
00362 (void)readBufSize;
00363 (void)writeBufSize;
00364
00365 m_handle = ::open(portName, O_RDWR | O_NOCTTY);
00366
00367
00368
00369
00370 if (m_handle < 0) {
00371
00372 return m_lastResult = XRV_INPUTCANNOTBEOPENED;
00373 }
00374
00375
00376 m_isOpen = true;
00377
00378
00379
00380 tcgetattr(m_handle, &m_commState);
00381
00382
00383 cfsetispeed(&m_commState, baudRate);
00384 cfsetospeed(&m_commState, baudRate);
00385
00386
00387 m_commState.c_cflag |= (CLOCAL | CREAD);
00388
00389 m_commState.c_cflag &= ~(CSIZE|PARENB);
00390 m_commState.c_cflag |= CS8;
00391 m_commState.c_cflag |= CSTOPB;
00392
00393 m_commState.c_cflag &= ~CRTSCTS;
00394 m_commState.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
00395
00396 m_commState.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
00397
00398 m_commState.c_oflag &= ~OPOST;
00399
00400 m_commState.c_cc[VMIN] = 0;
00401 m_commState.c_cc[VTIME] = (m_timeout+99)/100;
00402
00403
00404 tcsetattr(m_handle,TCSANOW, &m_commState);
00405
00406 m_port = 1;
00407 sprintf(m_portname, "%s", portName);
00408
00409 tcflush(m_handle, TCIOFLUSH);
00410
00411
00412 int cmbits;
00413 if (ioctl(m_handle, TIOCMGET, &cmbits) < 0)
00414 {
00415 return (m_lastResult = XRV_ERROR);
00416 }
00417
00418 cmbits |= TIOCM_RTS|TIOCM_DTR;
00419
00420 if (ioctl(m_handle, TIOCMSET, &cmbits) < 0)
00421 {
00422 return (m_lastResult = XRV_ERROR);
00423 }
00424 #endif // !_WIN32
00425
00426 CMT1LOG("L1: Port opened\n");
00427 return (m_lastResult = XRV_OK);
00428 }
00429
00430 #ifdef _WIN32
00431
00432
00433 XsensResultValue Cmt1s::open ( const uint32_t portNumber,
00434 const uint32_t baudRate,
00435 uint32_t readBufSize,
00436 uint32_t writeBufSize)
00437 {
00438 char comFileName[32];
00439
00440
00441 sprintf(comFileName, "COM%d", portNumber);
00442
00443 return Cmt1s::open(comFileName, baudRate, readBufSize, writeBufSize);
00444 }
00445 #endif
00446
00447
00448
00449 XsensResultValue Cmt1s::readData (const uint32_t maxLength, uint8_t* data,
00450 uint32_t* length)
00451 {
00452 CMT1LOG("L1: readData, maxlength=%u, length=%p\n",maxLength,length);
00453 uint32_t ln;
00454 if (length == NULL)
00455 length = &ln;
00456
00457 if (!m_isOpen)
00458 return (m_lastResult = XRV_NOPORTOPEN);
00459
00460 #ifdef _WIN32
00461 BOOL rres = ::ReadFile(m_handle, data, maxLength, length, NULL);
00462 CMT1LOG("L1: readData, ReadFile returns %u (%u)\n",rres,*length);
00463 if (m_onBytesReceived != NULL && *length > 0)
00464 {
00465 CmtBinaryData* bytes = (CmtBinaryData*) malloc(sizeof(CmtBinaryData));
00466 bytes->m_size = *length;
00467 bytes->m_portNr = m_port;
00468 memcpy(bytes->m_data,data,*length);
00469 #ifdef _LOG_CALLBACKS
00470 CMTLOG("C1: onBytesReceived(%d,(%d,%d),%p)\n",(int32_t) m_onBytesReceivedInstance, (int32_t) bytes->m_size, (int32_t) bytes->m_portNr, m_onBytesReceivedParam);
00471 #endif
00472 m_onBytesReceived(m_onBytesReceivedInstance,CMT_CALLBACK_ONBYTESRECEIVED,bytes,m_onBytesReceivedParam);
00473 }
00474
00475 if (!rres)
00476 {
00477 CMT1LOG("L1: readData, ReadFile returned error %u\n",::GetLastError());
00478 return (m_lastResult = XRV_ERROR);
00479 }
00480 #else
00481 *length = read(m_handle, data, maxLength);
00482 #endif
00483
00484 #ifdef _LOG_RX_TX
00485 if (*length > 0)
00486 {
00487 if (rx_log == NULL)
00488 {
00489 char fname[CMT_MAX_FILENAME_LENGTH];
00490 sprintf(fname,"rx_%03d_%d.log",(int32_t) m_port,m_baudrate);
00491 rx_log = fopen(fname,"wb");
00492 }
00493 fwrite(data,1,*length,rx_log);
00494 }
00495 #endif
00496
00497 CMT1LOG((length[0]?"L1: readData returned success, read %u of %u bytes, first: %02x\n":"L1: readData returned success, read %u bytes\n"),length[0],maxLength,data[0]);
00498 return (m_lastResult = XRV_OK);
00499 }
00500
00501
00502
00503 XsensResultValue Cmt1s::setCallbackFunction(CmtCallbackType tp, int32_t instance, CmtCallbackFunction func, void* param)
00504 {
00505 if (tp == CMT_CALLBACK_ONBYTESRECEIVED)
00506 {
00507 m_onBytesReceived = func;
00508 m_onBytesReceivedInstance = instance;
00509 m_onBytesReceivedParam = param;
00510 return m_lastResult = XRV_OK;
00511 }
00512 return m_lastResult = XRV_INVALIDPARAM;
00513 }
00514
00515
00516
00517 XsensResultValue Cmt1s::setTimeout (const uint32_t ms)
00518 {
00519 CMT1LOG("L1: Setting timeout to %u ms\n",ms);
00520
00521 m_timeout = ms;
00522 #ifdef _WIN32
00523
00524 COMMTIMEOUTS commTimeouts;
00525
00526 GetCommTimeouts(m_handle,&commTimeouts);
00527
00528
00529 if (m_timeout > 0)
00530 {
00531 commTimeouts.ReadIntervalTimeout = 0;
00532 commTimeouts.ReadTotalTimeoutConstant = m_timeout;
00533 commTimeouts.ReadTotalTimeoutMultiplier = 0;
00534 commTimeouts.WriteTotalTimeoutConstant = m_timeout;
00535 commTimeouts.WriteTotalTimeoutMultiplier = 0;
00536 }
00537 else
00538 {
00539
00540 commTimeouts.ReadIntervalTimeout = MAXDWORD;
00541 commTimeouts.ReadTotalTimeoutConstant = 0;
00542 commTimeouts.ReadTotalTimeoutMultiplier = 0;
00543 commTimeouts.WriteTotalTimeoutConstant = 0;
00544 commTimeouts.WriteTotalTimeoutMultiplier = 0;
00545 }
00546
00547 SetCommTimeouts(m_handle, &commTimeouts);
00548 #else
00549
00550 m_commState.c_cc[VMIN] = 0;
00551 m_commState.c_cc[VTIME] = (m_timeout+99)/100;
00552
00553
00554 if (m_isOpen)
00555 tcsetattr(m_handle,TCSANOW, &m_commState);
00556 #endif
00557 return (m_lastResult = XRV_OK);
00558 }
00559
00560
00561
00562 XsensResultValue Cmt1s::waitForData (const uint32_t maxLength,
00563 uint8_t* data, uint32_t* length)
00564 {
00565 CMT1LOG("L1: waitForData, mto=%u, length=%p\n",m_timeout,length);
00566 uint32_t timeout = m_timeout;
00567
00568 uint32_t ln;
00569 if (length == NULL)
00570 length = &ln;
00571 uint32_t eTime = getTimeOfDay(NULL) + timeout;
00572 uint32_t newLength = 0;
00573
00574 *length = 0;
00575 while ((*length < maxLength) && (getTimeOfDay() <= eTime))
00576 {
00577 readData(maxLength - *length, data + *length, &newLength);
00578 *length += newLength;
00579 }
00580 CMT1LOG("L1: waitForData result: read %u of %u bytes\n",length[0],maxLength);
00581
00582 if (length[0] < maxLength)
00583 return (m_lastResult = XRV_TIMEOUT);
00584 else
00585 return (m_lastResult = XRV_OK);
00586 }
00587
00588
00589
00590 XsensResultValue Cmt1s::writeData (const uint32_t length, const uint8_t* data,
00591 uint32_t* written)
00592 {
00593 uint32_t bytes;
00594 if (written == NULL)
00595 written = &bytes;
00596
00597 if (!m_isOpen)
00598 return (m_lastResult = XRV_NOPORTOPEN);
00599
00600 #ifdef _WIN32
00601 if (WriteFile(m_handle, data, length, written, NULL))
00602 {
00603 #ifdef _LOG_RX_TX
00604 if (written[0] > 0)
00605 {
00606 if (tx_log == NULL)
00607 {
00608 char fname[CMT_MAX_FILENAME_LENGTH];
00609 sprintf(fname,"tx_%03d_%d.log",(int32_t) m_port,m_baudrate);
00610 tx_log = fopen(fname,"wb");
00611 }
00612 fwrite(data,1,*written,tx_log);
00613 }
00614 #endif
00615 return (m_lastResult = XRV_OK);
00616 }
00617 else
00618 return (m_lastResult = XRV_ERROR);
00619 #else
00620 *written = write(m_handle, data, length);
00621
00622 return (m_lastResult = XRV_OK);
00623
00624
00625 #endif
00626 }
00627
00628
00629
00630
00631
00632
00633
00634 Cmt1f::Cmt1f()
00635 {
00636 m_readPos = 0;
00637 m_writePos = 0;
00638 m_lastResult = XRV_OK;
00639 m_reading = true;
00640 m_isOpen = false;
00641 m_filename[0] = '\0';
00642 m_fileSize = 0;
00643 m_readOnly = false;
00644 m_unicode = false;
00645 }
00646
00647
00648
00649 Cmt1f::~Cmt1f()
00650 {
00651 close();
00652 }
00653
00654
00655
00656 XsensResultValue Cmt1f::appendData (const uint32_t length, const void* data)
00657 {
00658 if (!m_isOpen)
00659 return m_lastResult = XRV_NOFILEOPEN;
00660 if (m_readOnly)
00661 return m_lastResult = XRV_READONLY;
00662
00663 if (m_reading || m_writePos != m_fileSize)
00664 {
00665 m_reading = false;
00666 FSEEK_R(0);
00667 }
00668 fwrite(data, 1, length, m_handle);
00669 m_writePos = FTELL();
00670 m_fileSize = m_writePos;
00671
00672 return (m_lastResult = XRV_OK);
00673 }
00674
00675
00676
00677 XsensResultValue Cmt1f::close (void)
00678 {
00679 if (m_isOpen)
00680 {
00681 #ifdef _WIN32
00682 fflush(m_handle);
00683 fclose(m_handle);
00684 #else
00685 ::fflush(m_handle);
00686 ::fclose(m_handle);
00687 #endif
00688 }
00689 m_isOpen = false;
00690 m_readPos = 0;
00691 m_writePos = 0;
00692 m_reading = true;
00693 m_isOpen = false;
00694 m_fileSize = 0;
00695 m_readOnly = false;
00696
00697 return m_lastResult = XRV_OK;
00698 }
00699
00700
00701
00702 XsensResultValue Cmt1f::closeAndDelete(void)
00703 {
00704 if (m_isOpen)
00705 {
00706 #ifdef _WIN32
00707 fflush(m_handle);
00708 fclose(m_handle);
00709 #else
00710 ::fflush(m_handle);
00711 ::fclose(m_handle);
00712 #endif
00713 if (m_readOnly)
00714 m_lastResult = XRV_READONLY;
00715 else
00716 {
00717 #ifdef _WIN32
00718 if (m_unicode)
00719 {
00720 if (_wremove(m_filename_w) != 0)
00721 m_lastResult = XRV_READONLY;
00722 else
00723 m_lastResult = XRV_OK;
00724 }
00725 else
00726 #endif
00727 {
00728 #ifdef _WIN32
00729 if (_unlink(m_filename) != 0)
00730 #else
00731 if (unlink(m_filename) != 0)
00732 #endif
00733 m_lastResult = XRV_READONLY;
00734 else
00735 m_lastResult = XRV_OK;
00736 }
00737 }
00738 }
00739 else
00740 m_lastResult = XRV_NOFILEOPEN;
00741
00742 m_isOpen = false;
00743 m_readPos = 0;
00744 m_writePos = 0;
00745 m_reading = true;
00746 m_isOpen = false;
00747 m_fileSize = 0;
00748 m_readOnly = false;
00749
00750 return m_lastResult;
00751 }
00752
00753
00754
00755 XsensResultValue Cmt1f::create (const char* filename)
00756 {
00757 if (m_isOpen)
00758 return m_lastResult = XRV_ALREADYOPEN;
00759
00760
00761 m_handle = fopen(filename, "w+b");
00762 if (m_handle == NULL)
00763 return m_lastResult = XRV_OUTPUTCANNOTBEOPENED;
00764
00765 #ifdef _WIN32
00766 if (_fullpath(m_filename,filename,CMT_MAX_FILENAME_LENGTH) == NULL)
00767 {
00768 fclose(m_handle);
00769 remove(filename);
00770 return m_lastResult = XRV_INVALIDPARAM;
00771 }
00772 #else
00773
00774
00775
00776 if (realpath(filename, m_filename) == NULL)
00777 {
00778 fclose(m_handle);
00779 remove(filename);
00780 return m_lastResult = XRV_INVALIDPARAM;
00781 }
00782 #endif
00783 mbstowcs(m_filename_w,m_filename,CMT_MAX_FILENAME_LENGTH);
00784 m_unicode = false;
00785
00786 m_isOpen = true;
00787 m_readPos = 0;
00788 m_writePos = 0;
00789 m_fileSize = 0;
00790 m_reading = true;
00791 m_readOnly = false;
00792 return m_lastResult = XRV_OK;
00793 }
00794
00795
00796
00797 XsensResultValue Cmt1f::create (const wchar_t* filename)
00798 {
00799 if (m_isOpen)
00800 return m_lastResult = XRV_ALREADYOPEN;
00801
00802 #ifdef _WIN32
00803
00804 m_handle = _wfopen(filename, L"w+b");
00805 if (m_handle == NULL)
00806 return m_lastResult = XRV_OUTPUTCANNOTBEOPENED;
00807
00808 if (_wfullpath(m_filename_w,filename,CMT_MAX_FILENAME_LENGTH) == NULL)
00809 {
00810 fclose(m_handle);
00811 _wremove(filename);
00812 return m_lastResult = XRV_INVALIDPARAM;
00813 }
00814 wcstombs(m_filename,m_filename_w,CMT_MAX_FILENAME_LENGTH);
00815
00816 m_isOpen = true;
00817 m_readPos = 0;
00818 m_writePos = 0;
00819 m_fileSize = 0;
00820 m_reading = true;
00821 m_readOnly = false;
00822 #else
00823 char tFilename[CMT_MAX_FILENAME_LENGTH*2];
00824 wcstombs(tFilename, filename, CMT_MAX_FILENAME_LENGTH);
00825 XsensResultValue res = create(tFilename);
00826 if (res != XRV_OK)
00827 return res;
00828 #endif
00829 m_unicode = true;
00830 return m_lastResult = XRV_OK;
00831 }
00832
00833
00834
00835 XsensResultValue Cmt1f::deleteData (const CmtFilePos start, const uint32_t length)
00836 {
00837 if (!m_isOpen)
00838 return m_lastResult = XRV_NOFILEOPEN;
00839 if (m_readOnly)
00840 return m_lastResult = XRV_READONLY;
00841
00842 gotoWrite();
00843
00844 CmtFilePos wPos = start;
00845 CmtFilePos rPos = wPos + length;
00846
00847 size_t read1;
00848 CmtFilePos endPos = (start + (CmtFilePos) length);
00849 if (endPos < m_fileSize)
00850 {
00851 CmtFilePos remaining = m_fileSize - endPos;
00852 char buffer[512];
00853
00854
00855 FSEEK(rPos);
00856
00857 while (remaining > 0)
00858 {
00859 if (remaining >= 512)
00860 read1 = fread(buffer,1,512,m_handle);
00861 else
00862 read1 = fread(buffer,1,(size_t) remaining,m_handle);
00863
00864 remaining -= read1;
00865 rPos += read1;
00866
00867
00868 FSEEK(wPos);
00869 wPos += fwrite(buffer, 1, read1, m_handle);
00870 FSEEK(rPos);
00871 }
00872 m_fileSize -= length;
00873 }
00874 else
00875 {
00876 m_fileSize = start;
00877 }
00878
00879 #ifdef _WIN32
00880 int32_t rv = _chsize(_fileno(m_handle),(int32_t) m_fileSize);
00881 #else
00882 int32_t rv = ftruncate(fileno(m_handle),(int32_t) m_fileSize);
00883 #endif
00884 int32_t eno = 0;
00885 if (rv != 0)
00886 eno = errno;
00887 m_writePos = start;
00888 FSEEK(wPos);
00889 if (rv != 0)
00890 {
00891 switch(eno)
00892 {
00893 case EACCES:
00894 return m_lastResult = XRV_BUSY;
00895 case EBADF:
00896 return m_lastResult = XRV_INVALIDINSTANCE;
00897 case ENOSPC:
00898 return m_lastResult = XRV_OUTOFMEMORY;
00899 case EINVAL:
00900 return m_lastResult = XRV_INVALIDPARAM;
00901 default:
00902 return m_lastResult = XRV_ERROR;
00903 }
00904 }
00905
00906 return m_lastResult = XRV_OK;
00907 }
00908
00909
00910
00911 XsensResultValue Cmt1f::find (const void* needleV, const uint32_t needleLength, CmtFilePos& pos)
00912 {
00913 if (!m_isOpen)
00914 return m_lastResult = XRV_NOFILEOPEN;
00915
00916 const char* needle = (const char*) needleV;
00917
00918 gotoRead();
00919
00920 pos = 0;
00921
00922 char buffer[512];
00923 uint32_t bufferPos, needlePos = 0;
00924 size_t readBytes;
00925 if (m_readPos & 0x1FF)
00926 readBytes = fread(buffer,1,(512-((size_t) m_readPos & 0x1FF)),m_handle);
00927 else
00928 readBytes = fread(buffer,1,512,m_handle);
00929
00930 while (readBytes > 0)
00931 {
00932 m_readPos += readBytes;
00933 bufferPos = 0;
00934
00935 while (bufferPos < readBytes && needlePos < needleLength)
00936 {
00937 if (buffer[bufferPos] == needle[needlePos])
00938 {
00939
00940 ++needlePos;
00941 }
00942 else
00943 {
00944 if (needlePos > 0)
00945 needlePos = 0;
00946 else
00947 if (buffer[bufferPos] == needle[0])
00948 {
00949
00950 needlePos = 1;
00951 }
00952 }
00953 ++bufferPos;
00954 }
00955 if (needlePos < needleLength)
00956 readBytes = fread(buffer,1,512,m_handle);
00957 else
00958 {
00959 m_readPos = m_readPos + bufferPos - readBytes - needleLength;
00960 pos = m_readPos;
00961 FSEEK(m_readPos);
00962 return m_lastResult = XRV_OK;
00963 }
00964 }
00965 return m_lastResult = XRV_ENDOFFILE;
00966 }
00967
00968
00969
00970 XsensResultValue Cmt1f::flushData (void)
00971 {
00972 fflush(m_handle);
00973
00974 return m_lastResult = XRV_OK;
00975 }
00976
00977
00978
00979 XsensResultValue Cmt1f::getName(char* filename) const
00980 {
00981 strcpy(filename, m_filename);
00982 return m_lastResult = XRV_OK;
00983 }
00984
00985
00986
00987 XsensResultValue Cmt1f::getName(wchar_t* filename) const
00988 {
00989 #ifdef _WIN32
00990 wcscpy(filename, m_filename_w);
00991 #else
00992 mbstowcs(filename, m_filename, CMT_MAX_FILENAME_LENGTH);
00993 #endif
00994 return m_lastResult = XRV_OK;
00995 }
00996
00997
00998
00999 void Cmt1f::gotoRead(void)
01000 {
01001 if (m_reading)
01002 return;
01003
01004 FSEEK(m_readPos);
01005 m_reading = true;
01006 }
01007
01008
01009
01010 void Cmt1f::gotoWrite(void)
01011 {
01012 if (!m_reading)
01013 return;
01014
01015 FSEEK(m_writePos);
01016 m_reading = false;
01017 }
01018
01019
01020
01021 XsensResultValue Cmt1f::insertData (const CmtFilePos start, const uint32_t length, const void* data)
01022 {
01023 if (!m_isOpen)
01024 return m_lastResult = XRV_NOFILEOPEN;
01025 if (m_readOnly)
01026 return m_lastResult = XRV_READONLY;
01027
01028 gotoWrite();
01029
01030 CmtFilePos rPos = start;
01031 CmtFilePos wPos = rPos + length;
01032
01033 size_t read1, read2;
01034 CmtFilePos remaining = m_fileSize - start;
01035 size_t bsize = (length > 512)?length:512;
01036 char* buffer1 = (char*) malloc(bsize);
01037 char* buffer2 = (char*) malloc(bsize);
01038 char* btemp;
01039
01040
01041 FSEEK(rPos);
01042
01043 if (remaining >= (CmtFilePos) bsize)
01044 read1 = fread(buffer1,1,bsize,m_handle);
01045 else
01046 read1 = fread(buffer1,1,(size_t) remaining,m_handle);
01047
01048 remaining -= read1;
01049 rPos += read1;
01050
01051 while(remaining > 0)
01052 {
01053
01054 read2 = read1;
01055 btemp = buffer1; buffer1 = buffer2; buffer2 = btemp;
01056
01057
01058 if (remaining >= (CmtFilePos) bsize)
01059 read1 = fread(buffer1,1,bsize,m_handle);
01060 else
01061 read1 = fread(buffer1,1,(size_t) remaining,m_handle);
01062
01063 remaining -= read1;
01064 rPos += read1;
01065
01066
01067 FSEEK(wPos);
01068 wPos += fwrite(buffer2, 1, read2, m_handle);
01069 FSEEK(rPos);
01070 }
01071
01072 FSEEK(wPos);
01073 wPos += fwrite(buffer1, 1, read1, m_handle);
01074
01075 FSEEK(start);
01076 m_writePos = start + fwrite(data, 1, length, m_handle);
01077 m_fileSize += length;
01078
01079 free(buffer1);
01080 free(buffer2);
01081 return m_lastResult = XRV_OK;
01082 }
01083
01084
01085
01086 XsensResultValue Cmt1f::open(const char* filename, const bool create, const bool readOnly)
01087 {
01088 if (m_isOpen)
01089 return m_lastResult = XRV_ALREADYOPEN;
01090
01091
01092 m_readOnly = readOnly;
01093 if (readOnly)
01094 m_handle = fopen(filename, "rb");
01095 else
01096 m_handle = fopen(filename, "r+b");
01097 if (m_handle == NULL)
01098 {
01099 if (create)
01100 m_handle = fopen(filename, "w+b");
01101 else
01102 {
01103 m_handle = fopen(filename, "rb");
01104 m_readOnly = true;
01105 }
01106 }
01107 if (m_handle == NULL)
01108 return m_lastResult = XRV_INPUTCANNOTBEOPENED;
01109
01110 #ifdef _WIN32
01111 if (_fullpath(m_filename,filename,CMT_MAX_FILENAME_LENGTH) == NULL)
01112 {
01113 fclose(m_handle);
01114 return m_lastResult = XRV_INVALIDPARAM;
01115 }
01116 #else
01117
01118 if (realpath(filename, m_filename) == NULL)
01119 {
01120 fclose(m_handle);
01121 return m_lastResult = XRV_INVALIDPARAM;
01122 }
01123 #endif
01124 mbstowcs(m_filename_w,m_filename,CMT_MAX_FILENAME_LENGTH);
01125 m_unicode = false;
01126
01127 m_isOpen = true;
01128 m_readPos = 0;
01129 m_writePos = 0;
01130 m_reading = true;
01131 FSEEK_R(0);
01132 m_fileSize = FTELL();
01133 FSEEK(0);
01134 return (m_lastResult = XRV_OK);
01135 }
01136
01137
01138
01139 XsensResultValue Cmt1f::open(const wchar_t* filename, const bool create, const bool readOnly)
01140 {
01141 if (m_isOpen)
01142 return m_lastResult = XRV_ALREADYOPEN;
01143
01144 #ifdef _WIN32
01145
01146 m_readOnly = readOnly;
01147 if (readOnly)
01148 m_handle = _wfopen(filename, L"rb");
01149 else
01150 m_handle = _wfopen(filename, L"r+b");
01151 if (m_handle == NULL)
01152 {
01153 if (create)
01154 m_handle = _wfopen(filename, L"w+b");
01155 else
01156 {
01157 m_handle = _wfopen(filename, L"rb");
01158 m_readOnly = true;
01159 }
01160 }
01161 if (m_handle == NULL)
01162 return m_lastResult = XRV_INPUTCANNOTBEOPENED;
01163
01164 if (_wfullpath(m_filename_w,filename,CMT_MAX_FILENAME_LENGTH) == NULL)
01165 {
01166 fclose(m_handle);
01167 return m_lastResult = XRV_INVALIDPARAM;
01168 }
01169 wcstombs(m_filename,m_filename_w,CMT_MAX_FILENAME_LENGTH);
01170
01171 m_isOpen = true;
01172 m_readPos = 0;
01173 m_writePos = 0;
01174 m_reading = true;
01175 FSEEK_R(0);
01176 m_fileSize = FTELL();
01177 FSEEK(0);
01178 #else
01179 char tFilename[CMT_MAX_FILENAME_LENGTH*2];
01180 wcstombs(tFilename,filename,CMT_MAX_FILENAME_LENGTH*2);
01181 XsensResultValue res = open(tFilename,create,readOnly);
01182 if (res != XRV_OK)
01183 return res;
01184 #endif
01185 m_unicode = true;
01186 return m_lastResult = XRV_OK;
01187 }
01188
01189
01190
01191 XsensResultValue Cmt1f::readData(const uint32_t maxLength, void* data, uint32_t* length)
01192 {
01193 if (!m_isOpen)
01194 return m_lastResult = XRV_NOFILEOPEN;
01195
01196 if (maxLength == 0)
01197 return m_lastResult = XRV_OK;
01198
01199 uint32_t len;
01200 if (length == NULL)
01201 length = &len;
01202
01203 gotoRead();
01204
01205 length[0] = (uint32_t) fread(data,1,maxLength,m_handle);
01206 if (length[0] == 0)
01207 return (m_lastResult = XRV_ENDOFFILE);
01208
01209 m_readPos += length[0];
01210 return m_lastResult = XRV_OK;
01211 }
01212
01213
01214
01215 XsensResultValue Cmt1f::readData (const uint32_t maxLength, const char terminator, void* dataV, uint32_t* length)
01216 {
01217 if (!m_isOpen)
01218 return m_lastResult = XRV_NOFILEOPEN;
01219
01220 uint32_t len;
01221 if (length == NULL)
01222 length = &len;
01223
01224 char* data = (char*) dataV;
01225 int32_t readChar;
01226
01227 gotoRead();
01228
01229 *length = 0;
01230 readChar = (uint32_t) fgetc(m_handle);
01231
01232 while (!feof(m_handle) && !ferror(m_handle))
01233 {
01234 data[*length] = (char) readChar;
01235 ++(*length);
01236 ++m_readPos;
01237
01238 if (((char) readChar == terminator) || ((*length) >= maxLength))
01239 return m_lastResult = XRV_OK;
01240 }
01241 return m_lastResult = XRV_ENDOFFILE;
01242 }
01243
01244
01245
01246 XsensResultValue Cmt1f::setReadPos (const CmtFilePos pos)
01247 {
01248 if (!m_isOpen)
01249 return m_lastResult = XRV_NOFILEOPEN;
01250
01251 if (m_readPos != pos)
01252 {
01253 m_readPos = pos;
01254 if (m_reading)
01255 FSEEK(m_readPos);
01256 }
01257
01258 return m_lastResult = XRV_OK;
01259 }
01260
01261
01262
01263 XsensResultValue Cmt1f::setWritePos(const CmtFilePos pos)
01264 {
01265 if (!m_isOpen)
01266 return m_lastResult = XRV_NOFILEOPEN;
01267 if (m_readOnly)
01268 return m_lastResult = XRV_READONLY;
01269
01270 if (pos == -1)
01271 {
01272 if (m_reading)
01273 m_reading = false;
01274 FSEEK_R(0);
01275 m_writePos = FTELL();
01276 }
01277 else
01278 {
01279 if (m_writePos != pos)
01280 {
01281 m_writePos = pos;
01282 if (!m_reading)
01283 FSEEK(m_writePos);
01284 }
01285 }
01286
01287 return m_lastResult = XRV_OK;
01288 }
01289
01290
01291
01292 XsensResultValue Cmt1f::writeData (const uint32_t length, const void* data)
01293 {
01294 if (!m_isOpen)
01295 return m_lastResult = XRV_NOFILEOPEN;
01296 if (m_readOnly)
01297 return m_lastResult = XRV_READONLY;
01298
01299 gotoWrite();
01300 size_t writeRes = fwrite(data, 1, length, m_handle);
01301 if (writeRes == (size_t)EOF || writeRes < length)
01302 {
01303 int32_t err = (int32_t)errno;
01304 switch (err)
01305 {
01306 case 0: break;
01307 case ENOSPC: return m_lastResult = XRV_INSUFFICIENTSPACE;
01308 case ENOMEM: return m_lastResult = XRV_OUTOFMEMORY;
01309 default: return m_lastResult = XRV_ERROR;
01310 }
01311 }
01312 m_writePos += writeRes;
01313
01314 if (m_writePos > m_fileSize)
01315 m_fileSize = m_writePos;
01316
01317 return m_lastResult = XRV_OK;
01318 }
01319
01320 }