Home | History | Annotate | Download | only in darwin-x86
      1 /*
      2  *  EASLib.c
      3  *  EASLIb
      4  *
      5  * Copyright (C) 2008 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *
     20  */
     21 
     22 #include <stdlib.h>
     23 #include <stdio.h>
     24 #include <stdarg.h>
     25 #include <string.h>
     26 
     27 #include "eas.h"
     28 #include "eas_report.h"
     29 #include "eas_host.h"
     30 
     31 #ifdef JET_INTERFACE
     32 #include "jet.h"
     33 #endif
     34 
     35 
     36 #define EAS_EXPORT __attribute__((visibility("default")))
     37 
     38 // #define DEBUG_FILE_IO
     39 
     40 /* include debug interface */
     41 #include "eas_host_debug.h"
     42 
     43 #ifdef AUX_MIXER
     44 #include "eas_auxmix.h"
     45 #endif
     46 
     47 /* this module requires dynamic memory support */
     48 #ifdef _STATIC_MEMORY
     49 #error "eas_hostmm.c requires the dynamic memory model!\n"
     50 #endif
     51 
     52 #ifndef EAS_MAX_FILE_HANDLES
     53 #define EAS_MAX_FILE_HANDLES    32
     54 #endif
     55 
     56 #ifndef EAS_FILE_BUFFER_SIZE
     57 #define EAS_FILE_BUFFER_SIZE    32
     58 #endif
     59 
     60 /*
     61  * this structure and the related function are here
     62  * to support the ability to create duplicate handles
     63  * and buffering it in memory. If your system uses
     64  * in-memory resources, you can eliminate the calls
     65  * to malloc and free, the dup flag, and simply track
     66  * the file size and read position.
     67  */
     68  #ifdef BUFFERED_FILE_ACCESS
     69 typedef struct eas_hw_file_tag
     70 {
     71     FILE *pFile;
     72     EAS_I32 bytesInBuffer;
     73     EAS_I32 readIndex;
     74     EAS_I32 filePos;
     75     EAS_I32 fileSize;
     76     EAS_BOOL dup;
     77     EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
     78 } EAS_HW_FILE;
     79 #else
     80 typedef struct eas_hw_file_tag
     81 {
     82     EAS_I32         fileSize;
     83     EAS_I32         filePos;
     84     EAS_BOOL        dup;
     85     EAS_U8          *buffer;
     86 } EAS_HW_FILE;
     87 #endif
     88 
     89 typedef struct eas_hw_inst_data_tag
     90 {
     91     EAS_HW_FILE     files[EAS_MAX_FILE_HANDLES];
     92 } EAS_HW_INST_DATA;
     93 
     94 EAS_BOOL errorConditions[eNumErrorConditions];
     95 EAS_BOOL ledState;
     96 EAS_BOOL vibState;
     97 EAS_BOOL backlightState;
     98 
     99 #define MAX_DEBUG_MSG_LEN 1024
    100 
    101 typedef void (*EAS_LOG_FUNC)(EAS_INT severity, char *msg);
    102 
    103 static EAS_LOG_FUNC logCallback = NULL;
    104 static char messageBuffer[MAX_DEBUG_MSG_LEN];
    105 
    106 /* error counts */
    107 static EAS_INT eas_fatalErrors;
    108 static EAS_INT eas_errors;
    109 static EAS_INT eas_warnings;
    110 static int severityLevel = 9999;
    111 
    112 /* wave out device */
    113 #ifndef MAX_WAVE_OUT_BUFFERS
    114 #define MAX_WAVE_OUT_BUFFERS            8
    115 #endif
    116 
    117 #ifndef EAS_BUFFERS_PER_WAVE_BUFFER
    118 #define EAS_BUFFERS_PER_WAVE_BUFFER     8
    119 #endif
    120 
    121 /*----------------------------------------------------------------------------
    122  * ResetErrorCounters()
    123  *----------------------------------------------------------------------------
    124 */
    125 EAS_EXPORT void ResetErrorCounters()
    126 {
    127     eas_fatalErrors = 0;
    128     eas_errors = 0;
    129     eas_warnings = 0;
    130 }
    131 
    132 /*----------------------------------------------------------------------------
    133  * SetLogCallback()
    134  *----------------------------------------------------------------------------
    135 */
    136 EAS_EXPORT void SetLogCallback (EAS_LOG_FUNC callback)
    137 {
    138     logCallback = callback;
    139 }
    140 
    141 #ifndef _NO_DEBUG_PREPROCESSOR
    142 static S_DEBUG_MESSAGES debugMessages[] =
    143 {
    144 #ifdef UNIFIED_DEBUG_MESSAGES
    145 #include "eas_debugmsgs.h"
    146 #endif
    147     { 0,0,0 }
    148 };
    149 
    150 /*----------------------------------------------------------------------------
    151  * EAS_ReportEx()
    152  *----------------------------------------------------------------------------
    153 */
    154 void EAS_ReportEx (int severity, unsigned long hashCode, int serialNum, ...)
    155 {
    156     va_list vargs;
    157     int i;
    158 
    159     switch (severity)
    160     {
    161         case _EAS_SEVERITY_FATAL:
    162             eas_fatalErrors++;
    163             break;
    164 
    165         case _EAS_SEVERITY_ERROR:
    166             eas_errors++;
    167             break;
    168 
    169         case _EAS_SEVERITY_WARNING:
    170             eas_warnings++;
    171             break;
    172 
    173         default:
    174             break;
    175     }
    176 
    177     /* check severity level */
    178     if (severity > severityLevel)
    179         return;
    180 
    181     /* check for callback */
    182     if (logCallback == NULL)
    183         return;
    184 
    185     /* find the error message and output to stdout */
    186     for (i = 0; debugMessages[i].m_pDebugMsg; i++)
    187     {
    188         if ((debugMessages[i].m_nHashCode == hashCode) &&
    189         (debugMessages[i].m_nSerialNum == serialNum))
    190         {
    191             va_start(vargs, serialNum);
    192 #ifdef WIN32
    193             vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
    194 #else
    195             vsprintf(messageBuffer, debugMessages[i].m_pDebugMsg, vargs);
    196 #endif
    197             logCallback(severity, messageBuffer);
    198             va_end(vargs);
    199             return;
    200         }
    201     }
    202     printf("Unrecognized error: Severity=%d; HashCode=%lu; SerialNum=%d\n", severity, hashCode, serialNum);
    203 } /* end EAS_ReportEx */
    204 
    205 #else
    206 /*----------------------------------------------------------------------------
    207  * EAS_Report()
    208  *----------------------------------------------------------------------------
    209 */
    210 void EAS_Report (int severity, const char *fmt, ...)
    211 {
    212     va_list vargs;
    213 
    214     switch (severity)
    215     {
    216         case _EAS_SEVERITY_FATAL:
    217             eas_fatalErrors++;
    218             break;
    219 
    220         case _EAS_SEVERITY_ERROR:
    221             eas_errors++;
    222             break;
    223 
    224         case _EAS_SEVERITY_WARNING:
    225             eas_warnings++;
    226             break;
    227 
    228         default:
    229             break;
    230     }
    231 
    232     /* check severity level */
    233     if (severity > severityLevel)
    234         return;
    235 
    236     /* check for callback */
    237     if (logCallback == NULL)
    238         return;
    239 
    240     va_start(vargs, fmt);
    241 #ifdef _WIN32
    242     vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
    243 #else
    244     vsprintf(messageBuffer, fmt, vargs);
    245 #endif
    246     logCallback(severity, messageBuffer);
    247     va_end(vargs);
    248 } /* end EAS_Report */
    249 
    250 /*----------------------------------------------------------------------------
    251  * EAS_ReportX()
    252  *----------------------------------------------------------------------------
    253 */
    254 void EAS_ReportX (int severity, const char *fmt, ...)
    255 {
    256     va_list vargs;
    257 
    258     switch (severity)
    259     {
    260         case _EAS_SEVERITY_FATAL:
    261             eas_fatalErrors++;
    262             break;
    263 
    264         case _EAS_SEVERITY_ERROR:
    265             eas_errors++;
    266             break;
    267 
    268         case _EAS_SEVERITY_WARNING:
    269             eas_warnings++;
    270             break;
    271 
    272         default:
    273             break;
    274     }
    275 
    276     /* check severity level */
    277     if (severity > severityLevel)
    278         return;
    279 
    280     /* check for callback */
    281     if (logCallback == NULL)
    282         return;
    283 
    284     va_start(vargs, fmt);
    285 #ifdef _WIN32
    286     vsprintf_s(messageBuffer, sizeof(messageBuffer), fmt, vargs);
    287 #else
    288     vsprintf(messageBuffer, fmt, vargs);
    289 #endif
    290     logCallback(severity, messageBuffer);
    291     va_end(vargs);
    292 }
    293 #endif
    294 
    295 /*----------------------------------------------------------------------------
    296  * EAS_DLLSetDebugLevel()
    297  *----------------------------------------------------------------------------
    298 */
    299 EAS_EXPORT void EAS_DLLSetDebugLevel (int severity)
    300 {
    301     severityLevel = severity;
    302 }
    303 
    304 /*----------------------------------------------------------------------------
    305  * EAS_ExSetDebugLevel()
    306  *----------------------------------------------------------------------------
    307 */
    308 void EAS_SetDebugLevel (int severity)
    309 {
    310     severityLevel = severity;
    311 }
    312 
    313 /*----------------------------------------------------------------------------
    314  * EAS_SelectLibrary()
    315  *----------------------------------------------------------------------------
    316 */
    317 EAS_EXPORT EAS_RESULT EAS_SelectLib (EAS_DATA_HANDLE pEASData, EAS_HANDLE streamHandle, EAS_BOOL testLib)
    318 {
    319     extern EAS_SNDLIB_HANDLE VMGetLibHandle(EAS_INT libNum);
    320     return EAS_SetSoundLibrary(pEASData, streamHandle, VMGetLibHandle(testLib ? 1 : 0));
    321 }
    322 
    323 
    324 #if defined(_DEBUG) && !defined(MSC)
    325 #include <crtdbg.h>
    326 /*----------------------------------------------------------------------------
    327  * EnableHeapDebug()
    328  *----------------------------------------------------------------------------
    329 */
    330 static void EnableHeapDebug (void)
    331 {
    332     int temp;
    333     temp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    334     temp |= _CRTDBG_ALLOC_MEM_DF;
    335     temp |= _CRTDBG_CHECK_ALWAYS_DF;
    336     temp |= _CRTDBG_LEAK_CHECK_DF;
    337 //  temp |= _CRTDBG_DELAY_FREE_MEM_DF;
    338     _CrtSetDbgFlag(temp);
    339 }
    340 
    341 /*----------------------------------------------------------------------------
    342  * HeapCheck()
    343  *----------------------------------------------------------------------------
    344  * Check heap status
    345  *----------------------------------------------------------------------------
    346 */
    347 void HeapCheck (void)
    348 {
    349     int heapStatus;
    350 
    351     /* Check heap status */
    352     heapStatus = _heapchk();
    353     if ((heapStatus == _HEAPOK) || (heapStatus == _HEAPEMPTY))
    354         return;
    355 
    356     EAS_ReportX(_EAS_SEVERITY_FATAL, "Heap corrupt\n" );
    357 }
    358 #endif
    359 
    360 
    361 /*----------------------------------------------------------------------------
    362  * EAS_HWInit
    363  *
    364  * Initialize host wrapper interface
    365  *
    366  *----------------------------------------------------------------------------
    367 */
    368 EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
    369 {
    370 
    371 #if defined(_DEBUG) && !defined(MSC)
    372     EnableHeapDebug();
    373 #endif
    374 
    375  #ifdef BUFFERED_FILE_ACCESS
    376     EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Buffered file access\n");
    377  #else
    378     EAS_ReportX(_EAS_SEVERITY_INFO, "EAS_HWInit: Memory mapped file access\n");
    379  #endif
    380 
    381     /* simulate failure */
    382     if (errorConditions[eInitError])
    383         return EAS_FAILURE;
    384 
    385     /* need to track file opens for duplicate handles */
    386     *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
    387     if (!(*pHWInstData))
    388         return EAS_ERROR_MALLOC_FAILED;
    389 
    390     EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
    391     return EAS_SUCCESS;
    392 }
    393 
    394 /*----------------------------------------------------------------------------
    395  * EAS_HWShutdown
    396  *
    397  * Shut down host wrapper interface
    398  *
    399  *----------------------------------------------------------------------------
    400 */
    401 EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
    402 {
    403 
    404     /* simulate failure */
    405     if (errorConditions[eShutdownError])
    406         return EAS_FAILURE;
    407 
    408     free(hwInstData);
    409 
    410 #if defined(_DEBUG) && !defined(MSC)
    411     HeapCheck();
    412 #endif
    413 
    414     return EAS_SUCCESS;
    415 }
    416 
    417 /*----------------------------------------------------------------------------
    418  *
    419  * EAS_HWMalloc
    420  *
    421  * Allocates dynamic memory
    422  *
    423  *----------------------------------------------------------------------------
    424 */
    425 /*lint -esym(715, hwInstData) available for customer use */
    426 void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
    427 {
    428     /* simulate failure */
    429     if (errorConditions[eMallocError])
    430         return NULL;
    431 
    432     return malloc((size_t) size);
    433 }
    434 
    435 /*----------------------------------------------------------------------------
    436  *
    437  * EAS_HWFree
    438  *
    439  * Frees dynamic memory
    440  *
    441  *----------------------------------------------------------------------------
    442 */
    443 /*lint -esym(715, hwInstData) available for customer use */
    444 void EAS_HWFree (EAS_HW_DATA_HANDLE hwInstData, void *p)
    445 {
    446     free(p);
    447 }
    448 
    449 /*----------------------------------------------------------------------------
    450  *
    451  * EAS_HWMemCpy
    452  *
    453  * Copy memory wrapper
    454  *
    455  *----------------------------------------------------------------------------
    456 */
    457 void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
    458 {
    459     return memcpy(dest, src, (size_t) amount);
    460 }
    461 
    462 /*----------------------------------------------------------------------------
    463  *
    464  * EAS_HWMemSet
    465  *
    466  * Set memory wrapper
    467  *
    468  *----------------------------------------------------------------------------
    469 */
    470 void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
    471 {
    472     return memset(dest, val, (size_t) amount);
    473 }
    474 
    475 /*----------------------------------------------------------------------------
    476  *
    477  * EAS_HWMemCmp
    478  *
    479  * Compare memory wrapper
    480  *
    481  *----------------------------------------------------------------------------
    482 */
    483 EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
    484 {
    485     return (EAS_I32) memcmp(s1, s2, (size_t) amount);
    486 }
    487 
    488 #ifdef BUFFERED_FILE_ACCESS
    489 /*----------------------------------------------------------------------------
    490  *
    491  * EAS_HWOpenFile
    492  *
    493  * Open a file for read or write
    494  *
    495  *----------------------------------------------------------------------------
    496 */
    497 EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
    498 {
    499     EAS_HW_FILE *file;
    500     int i;
    501 
    502     /* set return value to NULL */
    503     *pFile = NULL;
    504 
    505     /* only support read mode at this time */
    506     if (mode != EAS_FILE_READ)
    507         return EAS_ERROR_INVALID_FILE_MODE;
    508 
    509     /* find an empty entry in the file table */
    510     file = hwInstData->files;
    511     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    512     {
    513         /* is this slot being used? */
    514         if (file->pFile == NULL)
    515         {
    516             EAS_RESULT result;
    517 
    518             /* open the file */
    519             file->pFile = fopen((const char*) locator, "rb");
    520             if (file->pFile == NULL)
    521                 return EAS_ERROR_FILE_OPEN_FAILED;
    522 
    523             /* get file length */
    524             if ((result = EAS_HWFileLength(hwInstData, file, &file->fileSize)) != EAS_SUCCESS)
    525             {
    526                 EAS_HWCloseFile(hwInstData, file);
    527                 return result;
    528             }
    529 
    530 #ifdef DEBUG_FILE_IO
    531             EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
    532 #endif
    533 
    534             /* initialize some values */
    535             file->bytesInBuffer = 0;
    536             file->readIndex = 0;
    537             file->filePos = 0;
    538             file->dup = EAS_FALSE;
    539 
    540             *pFile = file;
    541             return EAS_SUCCESS;
    542         }
    543         file++;
    544     }
    545 
    546     /* too many open files */
    547     return EAS_ERROR_MAX_FILES_OPEN;
    548 }
    549 
    550 /*----------------------------------------------------------------------------
    551  *
    552  * EAS_HWFillBuffer
    553  *
    554  * Fill buffer from file
    555  *----------------------------------------------------------------------------
    556 */
    557 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    558 EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
    559 {
    560     /* reposition the file pointer */
    561     if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
    562         return EAS_ERROR_FILE_SEEK;
    563 
    564     /* read some data from the file */
    565     file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
    566     file->readIndex = 0;
    567     if (file->bytesInBuffer == 0)
    568         return EAS_EOF;
    569     return EAS_SUCCESS;
    570 }
    571 
    572 /*----------------------------------------------------------------------------
    573  *
    574  * EAS_HWReadFile
    575  *
    576  * Read data from a file
    577  *----------------------------------------------------------------------------
    578 */
    579 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    580 EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
    581 {
    582     EAS_RESULT result;
    583     EAS_I32 temp;
    584     EAS_U8 *p = pBuffer;
    585     EAS_I32 bytesLeft = n;
    586 
    587     *pBytesRead = 0;
    588 
    589     /* check handle integrity */
    590     if (file->pFile == NULL)
    591         return EAS_ERROR_INVALID_HANDLE;
    592 
    593 #ifdef DEBUG_FILE_IO
    594     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
    595 #endif
    596 
    597     /* try to fulfill request from buffer */
    598     for (;bytesLeft > 0;)
    599     {
    600         /* how many bytes can we get from buffer? */
    601         temp = file->bytesInBuffer - file->readIndex;
    602         if (temp > bytesLeft)
    603             temp = bytesLeft;
    604 
    605         /* copy data from buffer */
    606         EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
    607         *pBytesRead += temp;
    608         file->readIndex += temp;
    609         file->filePos += temp;
    610         p += temp;
    611         bytesLeft -= temp;
    612 
    613         /* don't refill buffer if request is bigger than buffer */
    614         if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
    615             break;
    616 
    617         /* refill buffer */
    618         if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
    619             return result;
    620     }
    621 
    622     /* more to read? do unbuffered read directly to target memory */
    623     if (bytesLeft)
    624     {
    625 
    626         /* position the file pointer */
    627         if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
    628             return EAS_ERROR_FILE_SEEK;
    629 
    630         /* read data in the buffer */
    631         temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
    632         *pBytesRead += temp;
    633         file->filePos += temp;
    634 
    635         /* reset buffer info */
    636         file->bytesInBuffer = 0;
    637         file->readIndex = 0;
    638     }
    639 
    640 #ifdef DEBUG_FILE_IO
    641     {
    642 #define BYTES_PER_LINE 16
    643         char str[BYTES_PER_LINE * 3 + 1];
    644         EAS_INT i;
    645         for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
    646             sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
    647         if (i)
    648             EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
    649     }
    650 #endif
    651 
    652     /* were n bytes read? */
    653     if (*pBytesRead != n)
    654         return EAS_EOF;
    655 
    656     return EAS_SUCCESS;
    657 }
    658 
    659 /*----------------------------------------------------------------------------
    660  *
    661  * EAS_HWGetByte
    662  *
    663  * Read a byte from a file
    664  *----------------------------------------------------------------------------
    665 */
    666 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    667 EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
    668 {
    669     EAS_RESULT result;
    670 
    671     /* check handle integrity */
    672     if (file->pFile == NULL)
    673         return EAS_ERROR_INVALID_HANDLE;
    674 
    675     /* use local buffer - do we have any data? */
    676     if (file->readIndex >= file->bytesInBuffer)
    677     {
    678         if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
    679             return result;
    680 
    681         /* if nothing to read, return EOF */
    682         if (file->bytesInBuffer == 0)
    683             return EAS_EOF;
    684     }
    685 
    686     /* get a character from the buffer */
    687     *((EAS_U8*) p) = file->buffer[file->readIndex++];
    688 
    689 #ifdef DEBUG_FILE_IO
    690     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
    691 #endif
    692 
    693     file->filePos++;
    694     return EAS_SUCCESS;
    695 }
    696 
    697 /*----------------------------------------------------------------------------
    698  *
    699  * EAS_HWGetWord
    700  *
    701  * Read a 16-bit value from the file
    702  *----------------------------------------------------------------------------
    703 */
    704 EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
    705 {
    706     EAS_RESULT result;
    707     EAS_I32 count;
    708     EAS_U8 c[2];
    709 
    710 #ifdef DEBUG_FILE_IO
    711     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
    712 #endif
    713 
    714     /* read 2 bytes from the file */
    715     if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
    716         return result;
    717 
    718     /* order them as requested */
    719     if (msbFirst)
    720         *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
    721     else
    722         *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
    723 
    724     return EAS_SUCCESS;
    725 }
    726 
    727 /*----------------------------------------------------------------------------
    728  *
    729  * EAS_HWGetDWord
    730  *
    731  * Read a 16-bit value from the file
    732  *----------------------------------------------------------------------------
    733 */
    734 EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
    735 {
    736     EAS_RESULT result;
    737     EAS_I32 count;
    738     EAS_U8 c[4];
    739 
    740 #ifdef DEBUG_FILE_IO
    741     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
    742 #endif
    743 
    744     /* read 4 bytes from the file */
    745     if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
    746         return result;
    747 
    748     /* order them as requested */
    749     if (msbFirst)
    750         *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
    751     else
    752         *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
    753 
    754     return EAS_SUCCESS;
    755 }
    756 
    757 /*----------------------------------------------------------------------------
    758  *
    759  * EAS_HWFilePos
    760  *
    761  * Returns the current location in the file
    762  *
    763  *----------------------------------------------------------------------------
    764 */
    765 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    766 EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
    767 {
    768 
    769     /* check handle integrity */
    770     if (file->pFile == NULL)
    771         return EAS_ERROR_INVALID_HANDLE;
    772 
    773     *pPosition = file->filePos;
    774     return EAS_SUCCESS;
    775 }
    776 
    777 /*----------------------------------------------------------------------------
    778  *
    779  * EAS_HWFileSeek
    780  *
    781  * Seek to a specific location in the file
    782  *
    783  *----------------------------------------------------------------------------
    784 */
    785 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    786 EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
    787 {
    788     EAS_I32 newIndex;
    789 
    790     /* check handle integrity */
    791     if (file->pFile == NULL)
    792         return EAS_ERROR_INVALID_HANDLE;
    793 
    794     /* check for seek past end */
    795     if ((position < 0) || (position > file->fileSize))
    796         return EAS_ERROR_FILE_SEEK;
    797 
    798 #ifdef DEBUG_FILE_IO
    799     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
    800 #endif
    801 
    802     /* is new position in current buffer? */
    803     newIndex = position - file->filePos + file->readIndex;
    804     if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
    805     {
    806         file->readIndex = newIndex;
    807         file->filePos = position;
    808         return EAS_SUCCESS;
    809     }
    810 
    811     /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
    812     file->filePos = position;
    813     file->bytesInBuffer = 0;
    814     file->readIndex = 0;
    815     return EAS_SUCCESS;
    816 }
    817 
    818 /*----------------------------------------------------------------------------
    819  *
    820  * EAS_HWFileSeekOfs
    821  *
    822  * Seek forward or back relative to the current position
    823  *
    824  *----------------------------------------------------------------------------
    825 */
    826 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    827 EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
    828 {
    829     EAS_I32 temp;
    830 
    831 #ifdef DEBUG_FILE_IO
    832     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
    833 #endif
    834 
    835     /* check handle integrity */
    836     if (file->pFile == NULL)
    837         return EAS_ERROR_INVALID_HANDLE;
    838 
    839     /* check for seek past end */
    840     temp = file->filePos + position;
    841     if ((temp < 0) || (temp > file->fileSize))
    842         return EAS_ERROR_FILE_SEEK;
    843 
    844     /* is new position in current buffer? */
    845     temp = position + file->readIndex;
    846     if ((temp >= 0) && (temp < file->bytesInBuffer))
    847     {
    848         file->readIndex = temp;
    849         file->filePos += position;
    850         return EAS_SUCCESS;
    851     }
    852 
    853     /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
    854     file->filePos += position;
    855     file->bytesInBuffer = 0;
    856     file->readIndex = 0;
    857     return EAS_SUCCESS;
    858 }
    859 
    860 /*----------------------------------------------------------------------------
    861  *
    862  * EAS_HWFileLength
    863  *
    864  * Return the file length
    865  *
    866  *----------------------------------------------------------------------------
    867 */
    868 /*lint -esym(715, hwInstData) hwInstData available for customer use */
    869 EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
    870 {
    871     long pos;
    872 
    873     /* check handle integrity */
    874     if (file->pFile == NULL)
    875         return EAS_ERROR_INVALID_HANDLE;
    876 
    877     if ((pos = ftell(file->pFile)) == -1L)
    878         return EAS_ERROR_FILE_LENGTH;
    879     if (fseek(file->pFile, 0L, SEEK_END) != 0)
    880         return EAS_ERROR_FILE_LENGTH;
    881     if ((*pLength = ftell(file->pFile)) == -1L)
    882         return EAS_ERROR_FILE_LENGTH;
    883     if (fseek(file->pFile, pos, SEEK_SET) != 0)
    884         return EAS_ERROR_FILE_LENGTH;
    885     return EAS_SUCCESS;
    886 }
    887 
    888 /*----------------------------------------------------------------------------
    889  *
    890  * EAS_HWDupHandle
    891  *
    892  * Duplicate a file handle
    893  *
    894  *----------------------------------------------------------------------------
    895 */
    896 EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
    897 {
    898     EAS_HW_FILE *dupfile;
    899     int i;
    900 
    901     /* check handle integrity */
    902     *pDupFile = NULL;
    903     if (file->pFile == NULL)
    904         return EAS_ERROR_INVALID_HANDLE;
    905 
    906     /* find an empty entry in the file table */
    907     dupfile = hwInstData->files;
    908     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    909     {
    910         /* is this slot being used? */
    911         if (dupfile->pFile == NULL)
    912         {
    913 
    914             /* copy info from the handle to be duplicated */
    915             dupfile->filePos = file->filePos;
    916             dupfile->pFile = file->pFile;
    917             dupfile->fileSize = file->fileSize;
    918 
    919             /* set the duplicate handle flag */
    920             dupfile->dup = file->dup = EAS_TRUE;
    921 
    922             /* initialize some values */
    923             dupfile->bytesInBuffer = 0;
    924             dupfile->readIndex = 0;
    925 
    926             *pDupFile = dupfile;
    927             return EAS_SUCCESS;
    928         }
    929         dupfile++;
    930     }
    931 
    932     /* too many open files */
    933     return EAS_ERROR_MAX_FILES_OPEN;
    934 }
    935 
    936 /*----------------------------------------------------------------------------
    937  *
    938  * EAS_HWClose
    939  *
    940  * Wrapper for fclose function
    941  *
    942  *----------------------------------------------------------------------------
    943 */
    944 EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
    945 {
    946     EAS_HW_FILE *file2,*dupFile;
    947     int i;
    948 
    949     /* check handle integrity */
    950     if (file1->pFile == NULL)
    951         return EAS_ERROR_INVALID_HANDLE;
    952 
    953     /* check for duplicate handle */
    954     if (file1->dup)
    955     {
    956         dupFile = NULL;
    957         file2 = hwInstData->files;
    958         for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
    959         {
    960             /* check for duplicate */
    961             if ((file1 != file2) && (file2->pFile == file1->pFile))
    962             {
    963                 /* is there more than one duplicate? */
    964                 if (dupFile != NULL)
    965                 {
    966                     /* clear this entry and return */
    967                     file1->pFile = NULL;
    968                     return EAS_SUCCESS;
    969                 }
    970 
    971                 /* this is the first duplicate found */
    972                 dupFile = file2;
    973             }
    974             file2++;
    975         }
    976 
    977         /* there is only one duplicate, clear the dup flag */
    978         if (dupFile)
    979             dupFile->dup = EAS_FALSE;
    980         else
    981             /* if we get here, there's a serious problem */
    982             return EAS_ERROR_HANDLE_INTEGRITY;
    983 
    984         /* clear this entry and return */
    985         file1->pFile = NULL;
    986         return EAS_SUCCESS;
    987     }
    988 
    989     /* no duplicates - close the file */
    990     if (fclose(file1->pFile) != 0)
    991         return EAS_ERROR_CLOSE_FAILED;
    992 
    993     /* clear this entry and return */
    994     file1->pFile = NULL;
    995     return EAS_SUCCESS;
    996 }
    997 #else
    998 /*----------------------------------------------------------------------------
    999  *
   1000  * EAS_HWOpenFile
   1001  *
   1002  * Open a file for read or write
   1003  *
   1004  *----------------------------------------------------------------------------
   1005 */
   1006 EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
   1007 {
   1008     EAS_HW_FILE *file;
   1009     FILE *ioFile;
   1010     int i, temp;
   1011 
   1012     /* set return value to NULL */
   1013     *pFile = NULL;
   1014 
   1015     /* simulate failure */
   1016     if (errorConditions[eOpenError])
   1017         return EAS_FAILURE;
   1018 
   1019     /* only support read mode at this time */
   1020     if (mode != EAS_FILE_READ)
   1021         return EAS_ERROR_INVALID_FILE_MODE;
   1022 
   1023     /* find an empty entry in the file table */
   1024     file = hwInstData->files;
   1025     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
   1026     {
   1027         /* is this slot being used? */
   1028         if (file->buffer == NULL)
   1029         {
   1030             /* open the file */
   1031             if ((ioFile = fopen(locator,"rb")) == NULL)
   1032                 return EAS_ERROR_FILE_OPEN_FAILED;
   1033 
   1034             /* determine the file size */
   1035             if (fseek(ioFile, 0L, SEEK_END) != 0)
   1036                 return EAS_ERROR_FILE_LENGTH;
   1037             if ((file->fileSize = ftell(ioFile)) == -1L)
   1038                 return EAS_ERROR_FILE_LENGTH;
   1039             if (fseek(ioFile, 0L, SEEK_SET) != 0)
   1040                 return EAS_ERROR_FILE_LENGTH;
   1041 
   1042             /* allocate a buffer */
   1043             file->buffer = EAS_HWMalloc(hwInstData, file->fileSize);
   1044             if (file->buffer == NULL)
   1045             {
   1046                 fclose(ioFile);
   1047                 return EAS_ERROR_MALLOC_FAILED;
   1048             }
   1049 
   1050             /* read the file into memory */
   1051             temp = (int) fread(file->buffer, (size_t) file->fileSize, 1, ioFile);
   1052 
   1053             /* close the file - don't need it any more */
   1054             fclose(ioFile);
   1055 
   1056             /* check for error reading file */
   1057             if (temp != 1)
   1058                 return EAS_ERROR_FILE_READ_FAILED;
   1059 
   1060             /* initialize some values */
   1061             file->filePos = 0;
   1062             file->dup = EAS_FALSE;
   1063 
   1064             *pFile = file;
   1065             return EAS_SUCCESS;
   1066         }
   1067         file++;
   1068     }
   1069 
   1070     /* too many open files */
   1071     return EAS_ERROR_MAX_FILES_OPEN;
   1072 }
   1073 
   1074 /*----------------------------------------------------------------------------
   1075  *
   1076  * EAS_HWReadFile
   1077  *
   1078  * Read data from a file
   1079  *
   1080  *----------------------------------------------------------------------------
   1081 */
   1082 /*lint -esym(715, hwInstData) available for customer use */
   1083 EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
   1084 {
   1085     EAS_I32 count;
   1086 
   1087     /* simulate failure */
   1088     if (errorConditions[eReadError])
   1089         return EAS_FAILURE;
   1090 
   1091     /* make sure we have a valid handle */
   1092     if (file->buffer == NULL)
   1093         return EAS_ERROR_INVALID_HANDLE;
   1094 
   1095     /* calculate the bytes to read */
   1096     count = file->fileSize - file->filePos;
   1097     if (n < count)
   1098         count = n;
   1099 
   1100     /* copy the data to the requested location, and advance the pointer */
   1101     if (count)
   1102         EAS_HWMemCpy(pBuffer, &file->buffer[file->filePos], count);
   1103     file->filePos += count;
   1104     *pBytesRead = count;
   1105 
   1106     /* were n bytes read? */
   1107     if (count!= n)
   1108         return EAS_EOF;
   1109     return EAS_SUCCESS;
   1110 }
   1111 
   1112 /*----------------------------------------------------------------------------
   1113  *
   1114  * EAS_HWGetByte
   1115  *
   1116  * Read a byte from a file
   1117  *
   1118  *----------------------------------------------------------------------------
   1119 */
   1120 /*lint -e{715} hwInstData available for customer use */
   1121 EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
   1122 {
   1123 
   1124     /* simulate failure */
   1125     if (errorConditions[eReadError])
   1126         return EAS_FAILURE;
   1127 
   1128     /* make sure we have a valid handle */
   1129     if (file->buffer == NULL)
   1130         return EAS_ERROR_INVALID_HANDLE;
   1131 
   1132     /* check for end of file */
   1133     if (file->filePos >= file->fileSize)
   1134     {
   1135         *((EAS_U8*) p) = 0;
   1136         return EAS_EOF;
   1137     }
   1138 
   1139     /* get a character from the buffer */
   1140     *((EAS_U8*) p) = file->buffer[file->filePos++];
   1141     return EAS_SUCCESS;
   1142 }
   1143 
   1144 /*----------------------------------------------------------------------------
   1145  *
   1146  * EAS_HWGetWord
   1147  *
   1148  * Returns the current location in the file
   1149  *
   1150  *----------------------------------------------------------------------------
   1151 */
   1152 /*lint -esym(715, hwInstData) available for customer use */
   1153 EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
   1154 {
   1155     EAS_RESULT result;
   1156     EAS_U8 c1, c2;
   1157 
   1158     /* read 2 bytes from the file */
   1159     if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
   1160         return result;
   1161     if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
   1162         return result;
   1163 
   1164     /* order them as requested */
   1165     if (msbFirst)
   1166         *((EAS_U16*) p) = ((EAS_U16) c1 << 8) | c2;
   1167     else
   1168         *((EAS_U16*) p) = ((EAS_U16) c2 << 8) | c1;
   1169 
   1170     return EAS_SUCCESS;
   1171 }
   1172 
   1173 /*----------------------------------------------------------------------------
   1174  *
   1175  * EAS_HWGetDWord
   1176  *
   1177  * Returns the current location in the file
   1178  *
   1179  *----------------------------------------------------------------------------
   1180 */
   1181 /*lint -esym(715, hwInstData) available for customer use */
   1182 EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
   1183 {
   1184     EAS_RESULT result;
   1185     EAS_U8 c1, c2,c3,c4;
   1186 
   1187     /* read 4 bytes from the file */
   1188     if ((result = EAS_HWGetByte(hwInstData, file, &c1)) != EAS_SUCCESS)
   1189         return result;
   1190     if ((result = EAS_HWGetByte(hwInstData, file, &c2)) != EAS_SUCCESS)
   1191         return result;
   1192     if ((result = EAS_HWGetByte(hwInstData, file, &c3)) != EAS_SUCCESS)
   1193         return result;
   1194     if ((result = EAS_HWGetByte(hwInstData, file, &c4)) != EAS_SUCCESS)
   1195         return result;
   1196 
   1197     /* order them as requested */
   1198     if (msbFirst)
   1199         *((EAS_U32*) p) = ((EAS_U32) c1 << 24) | ((EAS_U32) c2 << 16) | ((EAS_U32) c3 << 8) | c4;
   1200     else
   1201         *((EAS_U32*) p)= ((EAS_U32) c4 << 24) | ((EAS_U32) c3 << 16) | ((EAS_U32) c2 << 8) | c1;
   1202 
   1203     return EAS_SUCCESS;
   1204 }
   1205 
   1206 /*----------------------------------------------------------------------------
   1207  *
   1208  * EAS_HWFilePos
   1209  *
   1210  * Returns the current location in the file
   1211  *
   1212  *----------------------------------------------------------------------------
   1213 */
   1214 /*lint -esym(715, hwInstData) available for customer use */
   1215 EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
   1216 {
   1217 
   1218     /* simulate failure */
   1219     if (errorConditions[ePosError])
   1220         return EAS_FAILURE;
   1221 
   1222     /* make sure we have a valid handle */
   1223     if (file->buffer == NULL)
   1224         return EAS_ERROR_INVALID_HANDLE;
   1225 
   1226     *pPosition = file->filePos;
   1227     return EAS_SUCCESS;
   1228 } /* end EAS_HWFilePos */
   1229 
   1230 /*----------------------------------------------------------------------------
   1231  *
   1232  * EAS_HWFileSeek
   1233  *
   1234  * Seek to a specific location in the file
   1235  *
   1236  *----------------------------------------------------------------------------
   1237 */
   1238 /*lint -esym(715, hwInstData) available for customer use */
   1239 EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
   1240 {
   1241 
   1242     /* simulate failure */
   1243     if (errorConditions[eSeekError])
   1244         return EAS_FAILURE;
   1245 
   1246     /* make sure we have a valid handle */
   1247     if (file->buffer == NULL)
   1248         return EAS_ERROR_INVALID_HANDLE;
   1249 
   1250     /* validate new position */
   1251     if ((position < 0) || (position > file->fileSize))
   1252         return EAS_ERROR_FILE_SEEK;
   1253 
   1254     /* save new position */
   1255     file->filePos = position;
   1256     return EAS_SUCCESS;
   1257 }
   1258 
   1259 /*----------------------------------------------------------------------------
   1260  *
   1261  * EAS_HWFileSeekOfs
   1262  *
   1263  * Seek forward or back relative to the current position
   1264  *
   1265  *----------------------------------------------------------------------------
   1266 */
   1267 /*lint -esym(715, hwInstData) available for customer use */
   1268 EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
   1269 {
   1270 
   1271     /* simulate failure */
   1272     if (errorConditions[eSeekError])
   1273         return EAS_FAILURE;
   1274 
   1275     /* make sure we have a valid handle */
   1276     if (file->buffer == NULL)
   1277         return EAS_ERROR_INVALID_HANDLE;
   1278 
   1279     /* determine the file position */
   1280     position += file->filePos;
   1281     if ((position < 0) || (position > file->fileSize))
   1282         return EAS_ERROR_FILE_SEEK;
   1283 
   1284     /* save new position */
   1285     file->filePos = position;
   1286     return EAS_SUCCESS;
   1287 }
   1288 
   1289 /*----------------------------------------------------------------------------
   1290  *
   1291  * EAS_HWFileLength
   1292  *
   1293  * Return the file length
   1294  *
   1295  *----------------------------------------------------------------------------
   1296 */
   1297 /*lint -esym(715, hwInstData) available for customer use */
   1298 EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
   1299 {
   1300 
   1301     /* simulate failure */
   1302     if (errorConditions[eLengthError])
   1303         return EAS_FAILURE;
   1304 
   1305     /* make sure we have a valid handle */
   1306     if (file->buffer == NULL)
   1307         return EAS_ERROR_INVALID_HANDLE;
   1308 
   1309     *pLength = file->fileSize;
   1310     return EAS_SUCCESS;
   1311 }
   1312 
   1313 /*----------------------------------------------------------------------------
   1314  *
   1315  * EAS_HWDupHandle
   1316  *
   1317  * Duplicate a file handle
   1318  *
   1319  *----------------------------------------------------------------------------
   1320 */
   1321 EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE *pDupFile)
   1322 {
   1323     EAS_HW_FILE *dupFile;
   1324     int i;
   1325 
   1326     /* simulate failure */
   1327     if (errorConditions[eDupError])
   1328         return EAS_FAILURE;
   1329 
   1330     /* make sure we have a valid handle */
   1331     if (file->buffer == NULL)
   1332         return EAS_ERROR_INVALID_HANDLE;
   1333 
   1334     /* find an empty entry in the file table */
   1335     dupFile = hwInstData->files;
   1336     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
   1337     {
   1338         /* is this slot being used? */
   1339         if (dupFile->buffer == NULL)
   1340         {
   1341 
   1342             /* copy info from the handle to be duplicated */
   1343             dupFile->filePos = file->filePos;
   1344             dupFile->fileSize = file->fileSize;
   1345             dupFile->buffer = file->buffer;
   1346 
   1347             /* set the duplicate handle flag */
   1348             dupFile->dup = file->dup = EAS_TRUE;
   1349 
   1350             *pDupFile = dupFile;
   1351             return EAS_SUCCESS;
   1352         }
   1353         dupFile++;
   1354     }
   1355 
   1356     /* too many open files */
   1357     return EAS_ERROR_MAX_FILES_OPEN;
   1358 }
   1359 
   1360 /*----------------------------------------------------------------------------
   1361  *
   1362  * EAS_HWClose
   1363  *
   1364  * Wrapper for fclose function
   1365  *
   1366  *----------------------------------------------------------------------------
   1367 */
   1368 EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
   1369 {
   1370     EAS_HW_FILE *file2,*dupFile;
   1371     int i;
   1372 
   1373     /* simulate failure */
   1374     if (errorConditions[eCloseError])
   1375         return EAS_FAILURE;
   1376 
   1377     /* make sure we have a valid handle */
   1378     if (file1->buffer == NULL)
   1379         return EAS_ERROR_INVALID_HANDLE;
   1380 
   1381     /* check for duplicate handle */
   1382     if (file1->dup)
   1383     {
   1384         dupFile = NULL;
   1385         file2 = hwInstData->files;
   1386         for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
   1387         {
   1388             /* check for duplicate */
   1389             if ((file1 != file2) && (file2->buffer == file1->buffer))
   1390             {
   1391                 /* is there more than one duplicate? */
   1392                 if (dupFile != NULL)
   1393                 {
   1394                     /* clear this entry and return */
   1395                     file1->buffer = NULL;
   1396                     return EAS_SUCCESS;
   1397                 }
   1398 
   1399                 /* this is the first duplicate found */
   1400                 else
   1401                     dupFile = file2;
   1402             }
   1403             file2++;
   1404         }
   1405 
   1406         /* there is only one duplicate, clear the dup flag */
   1407         if (dupFile)
   1408             dupFile->dup = EAS_FALSE;
   1409         else
   1410             /* if we get here, there's a serious problem */
   1411             return EAS_ERROR_HANDLE_INTEGRITY;
   1412 
   1413         /* clear this entry and return */
   1414         file1->buffer = NULL;
   1415         return EAS_SUCCESS;
   1416     }
   1417 
   1418     /* no duplicates -free the buffer */
   1419     EAS_HWFree(hwInstData, file1->buffer);
   1420 
   1421     /* clear this entry and return */
   1422     file1->buffer = NULL;
   1423     return EAS_SUCCESS;
   1424 }
   1425 #endif
   1426 
   1427 /*----------------------------------------------------------------------------
   1428  *
   1429  * EAS_HWVibrate
   1430  *
   1431  * Turn on/off vibrate function
   1432  *
   1433  *----------------------------------------------------------------------------
   1434 */
   1435 /*lint -esym(715, hwInstData) available for customer use */
   1436 EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
   1437 {
   1438     vibState = state;
   1439 //  EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
   1440     return EAS_SUCCESS;
   1441 } /* end EAS_HWVibrate */
   1442 
   1443 /*----------------------------------------------------------------------------
   1444  *
   1445  * EAS_HWLED
   1446  *
   1447  * Turn on/off LED
   1448  *
   1449  *----------------------------------------------------------------------------
   1450 */
   1451 /*lint -esym(715, hwInstData) available for customer use */
   1452 EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
   1453 {
   1454     ledState = state;
   1455 //  EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
   1456     return EAS_SUCCESS;
   1457 }
   1458 
   1459 /*----------------------------------------------------------------------------
   1460  *
   1461  * EAS_HWBackLight
   1462  *
   1463  * Turn on/off backlight
   1464  *
   1465  *----------------------------------------------------------------------------
   1466 */
   1467 /*lint -esym(715, hwInstData) available for customer use */
   1468 EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
   1469 {
   1470     backlightState = state;
   1471 //  EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
   1472     return EAS_SUCCESS;
   1473 }
   1474 
   1475 /*----------------------------------------------------------------------------
   1476  *
   1477  * EAS_HWYield
   1478  *
   1479  * This function is called periodically by the EAS library to give the
   1480  * host an opportunity to allow other tasks to run. There are two ways to
   1481  * use this call:
   1482  *
   1483  * If you have a multi-tasking OS, you can call the yield function in the
   1484  * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
   1485  * the EAS library to continue processing when control returns from this
   1486  * function.
   1487  *
   1488  * If tasks run in a single thread by sequential function calls (sometimes
   1489  * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
   1490  * return to the caller. Be sure to check the number of bytes rendered
   1491  * before passing the audio buffer to the codec - it may not be filled.
   1492  * The next call to EAS_Render will continue processing until the buffer
   1493  * has been filled.
   1494  *
   1495  *----------------------------------------------------------------------------
   1496 */
   1497 /*lint -esym(715, hwInstData) available for customer use */
   1498 EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
   1499 {
   1500     /* put your code here */
   1501     return EAS_FALSE;
   1502 }
   1503 
   1504 
   1505