1 /*----------------------------------------------------------------------------
2  *
3  * File:
4  * eas_host.c
5  *
6  * Contents and purpose:
7  * This file contains the host wrapper functions for stdio, stdlib, etc.
8  * This is a sample version that wraps the standard library functions.
9  * Modify this file to suit the needs of your particular system.
10  *
11  * EAS_MAX_FILE_HANDLES sets the maximum number of MIDI streams within
12  * a MIDI type 1 file that can be played. To maintain efficiency, data
13  * is buffered locally when byte access is used (EAS_HWGetByte). The
14  * size of the buffer is set by EAS_FILE_BUFFER_SIZE.
15  *
16  * EAS_HW_FILE is a structure to support local file buffering. It
17  * comprises the OS File handle, some data related to the local file
18  * buffer, the position of the next byte of data to be read, the dup
19  * flag which when set, indicates that the handle has been duplicated,
20  * and the data buffer. Since the data buffer is only used for byte
21  * access, it does not need to be large.
22  *
23  * If the file system supports duplicate file handles and buffering,
24  * this entire subsystem can be replaced with direct calls to the
25  * native file I/O routines.
26  *
27  * If the system has enough memory to support reading the entire file
28  * into memory, it will be much more efficient to do so on the call to
29  * EAS_HWOpenFile and then close the file. Simply substitute a memory
30  * pointer for the FILE* pointer. Calls to EAS_HW_DupHandle will work
31  * as they do in this version. In the call to EAS_HWCloseFile, instead
32  * of calling fclose, free the memory containing the file data.
33  *
34  * Copyright 2005 Sonic Network Inc.
35 
36  * Licensed under the Apache License, Version 2.0 (the "License");
37  * you may not use this file except in compliance with the License.
38  * You may obtain a copy of the License at
39  *
40  *      http://www.apache.org/licenses/LICENSE-2.0
41  *
42  * Unless required by applicable law or agreed to in writing, software
43  * distributed under the License is distributed on an "AS IS" BASIS,
44  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45  * See the License for the specific language governing permissions and
46  * limitations under the License.
47  *
48  *----------------------------------------------------------------------------
49  * Revision Control:
50  *   $Revision: 853 $
51  *   $Date: 2007-09-05 09:54:17 -0700 (Wed, 05 Sep 2007) $
52  *----------------------------------------------------------------------------
53 */
54 
55 #ifdef _lint
56 #include "lint_stdlib.h"
57 #else
58 #include <stdio.h>
59 #include <stdlib.h>
60 #include <string.h>
61 #endif
62 
63 #include "eas_host.h"
64 
65 // #define DEBUG_FILE_IO
66 
67 /* Only for debugging LED, vibrate, and backlight functions */
68 #include "eas_report.h"
69 
70 #ifndef EAS_MAX_FILE_HANDLES
71 #define EAS_MAX_FILE_HANDLES    32
72 #endif
73 
74 #ifndef EAS_FILE_BUFFER_SIZE
75 #define EAS_FILE_BUFFER_SIZE    32
76 #endif
77 
78 /*
79  * this structure and the related function are here
80  * to support the ability to create duplicate handles
81  * and buffering into a single file. If the OS supports
82  * duplicate file handles natively, this code can be
83  * stripped to eliminate double-buffering.
84  */
85 typedef struct eas_hw_file_tag
86 {
87     FILE *pFile;
88     EAS_I32 bytesInBuffer;
89     EAS_I32 readIndex;
90     EAS_I32 filePos;
91     EAS_BOOL dup;
92     EAS_U8 buffer[EAS_FILE_BUFFER_SIZE];
93 } EAS_HW_FILE;
94 
95 typedef struct eas_hw_inst_data_tag
96 {
97     EAS_HW_FILE files[EAS_MAX_FILE_HANDLES];
98 } EAS_HW_INST_DATA;
99 
100 /* local memory for files and streams */
101 #ifdef _STATIC_MEMORY
102 EAS_HW_INST_DATA fileData;
103 #endif
104 
105 /*----------------------------------------------------------------------------
106  * EAS_HWInit
107  *
108  * Initialize host wrapper interface
109  *
110  *----------------------------------------------------------------------------
111 */
EAS_HWInit(EAS_HW_DATA_HANDLE * pHWInstData)112 EAS_RESULT EAS_HWInit (EAS_HW_DATA_HANDLE *pHWInstData)
113 {
114 
115     /* need to track file opens for duplicate handles */
116 #ifndef _STATIC_MEMORY
117     *pHWInstData = malloc(sizeof(EAS_HW_INST_DATA));
118     if (!(*pHWInstData))
119         return EAS_ERROR_MALLOC_FAILED;
120 #else
121     *pHWInstData = &fileData;
122 #endif
123     EAS_HWMemSet(*pHWInstData, 0, sizeof(EAS_HW_INST_DATA));
124     return EAS_SUCCESS;
125 }
126 
127 /*----------------------------------------------------------------------------
128  * EAS_HWShutdown
129  *
130  * Shut down host wrapper interface
131  *
132  *----------------------------------------------------------------------------
133 */
134 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWShutdown(EAS_HW_DATA_HANDLE hwInstData)135 EAS_RESULT EAS_HWShutdown (EAS_HW_DATA_HANDLE hwInstData)
136 {
137 
138 #ifndef _STATIC_MEMORY
139     free(hwInstData);
140 #endif
141     return EAS_SUCCESS;
142 }
143 
144 /*----------------------------------------------------------------------------
145  *
146  * EAS_HWMalloc
147  *
148  * Allocates dynamic memory
149  *
150  *----------------------------------------------------------------------------
151 */
152 /*lint -esym(715, hwInstData) hwInstData available for customer use */
153 #ifdef _STATIC_MEMORY
154 /*lint -esym(715, size) not used in static memory model */
155 #endif
EAS_HWMalloc(EAS_HW_DATA_HANDLE hwInstData,EAS_I32 size)156 void *EAS_HWMalloc (EAS_HW_DATA_HANDLE hwInstData, EAS_I32 size)
157 {
158 #ifdef _STATIC_MEMORY
159     return NULL;
160 #else
161     return malloc((EAS_U32)size);
162 #endif
163 }
164 
165 /*----------------------------------------------------------------------------
166  *
167  * EAS_HWFree
168  *
169  * Frees dynamic memory
170  *
171  *----------------------------------------------------------------------------
172 */
173 /*lint -esym(715, hwInstData) hwInstData available for customer use */
174 #ifdef _STATIC_MEMORY
175 /*lint -esym(715, p) not used in static memory model */
176 #endif
EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData,void * p)177 void EAS_HWFree(EAS_HW_DATA_HANDLE hwInstData, void *p)
178 {
179 #ifndef _STATIC_MEMORY
180     free(p);
181 #endif
182 }
183 
184 /*----------------------------------------------------------------------------
185  *
186  * EAS_HWMemCpy
187  *
188  * Copy memory wrapper
189  *
190  *----------------------------------------------------------------------------
191 */
EAS_HWMemCpy(void * dest,const void * src,EAS_I32 amount)192 void *EAS_HWMemCpy (void *dest, const void *src, EAS_I32 amount)
193 {
194     return memcpy(dest,src,(size_t) amount);
195 }
196 
197 /*----------------------------------------------------------------------------
198  *
199  * EAS_HWMemSet
200  *
201  * Set memory wrapper
202  *
203  *----------------------------------------------------------------------------
204 */
EAS_HWMemSet(void * dest,int val,EAS_I32 amount)205 void *EAS_HWMemSet (void *dest, int val, EAS_I32 amount)
206 {
207     return memset(dest,val,(size_t) amount);
208 }
209 
210 /*----------------------------------------------------------------------------
211  *
212  * EAS_HWMemCmp
213  *
214  * Compare memory wrapper
215  *
216  *----------------------------------------------------------------------------
217 */
EAS_HWMemCmp(const void * s1,const void * s2,EAS_I32 amount)218 EAS_I32 EAS_HWMemCmp (const void *s1, const void *s2, EAS_I32 amount)
219 {
220     return (EAS_I32) memcmp(s1, s2, (size_t) amount);
221 }
222 
223 /*----------------------------------------------------------------------------
224  *
225  * EAS_HWOpenFile
226  *
227  * Open a file for read or write
228  *
229  *----------------------------------------------------------------------------
230 */
EAS_HWOpenFile(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_LOCATOR locator,EAS_FILE_HANDLE * pFile,EAS_FILE_MODE mode)231 EAS_RESULT EAS_HWOpenFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_LOCATOR locator, EAS_FILE_HANDLE *pFile, EAS_FILE_MODE mode)
232 {
233     EAS_HW_FILE *file;
234     int i;
235 
236     /* set return value to NULL */
237     *pFile = NULL;
238 
239     /* only support read mode at this time */
240     if (mode != EAS_FILE_READ)
241         return EAS_ERROR_INVALID_FILE_MODE;
242 
243     /* find an empty entry in the file table */
244     file = hwInstData->files;
245     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
246     {
247         /* is this slot being used? */
248         if (file->pFile == NULL)
249         {
250             /* open the file */
251             if (locator->path)
252                 file->pFile = fopen((const char*) locator->path, "rb");
253             if (file->pFile == NULL)
254                 return EAS_ERROR_FILE_OPEN_FAILED;
255 
256 #ifdef DEBUG_FILE_IO
257             EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWOpenFile: Open file %d\n", i);
258 #endif
259 
260             /* initialize some values */
261             file->bytesInBuffer = 0;
262             file->readIndex = 0;
263             file->filePos = 0;
264             file->dup = EAS_FALSE;
265 
266             *pFile = file;
267             return EAS_SUCCESS;
268         }
269         file++;
270     }
271 
272     /* too many open files */
273     return EAS_ERROR_MAX_FILES_OPEN;
274 }
275 
276 /*----------------------------------------------------------------------------
277  *
278  * EAS_HWFillBuffer
279  *
280  * Fill buffer from file
281  *----------------------------------------------------------------------------
282 */
283 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWFillBuffer(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file)284 EAS_RESULT EAS_HWFillBuffer (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file)
285 {
286     /* reposition the file pointer */
287     if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
288         return EAS_ERROR_FILE_SEEK;
289 
290     /* read some data from the file */
291     file->bytesInBuffer = (EAS_I32) fread(file->buffer, 1, EAS_FILE_BUFFER_SIZE, file->pFile);
292     file->readIndex = 0;
293     if (file->bytesInBuffer == 0)
294         return EAS_EOF;
295     return EAS_SUCCESS;
296 }
297 
298 /*----------------------------------------------------------------------------
299  *
300  * EAS_HWReadFile
301  *
302  * Read data from a file
303  *----------------------------------------------------------------------------
304 */
305 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWReadFile(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,void * pBuffer,EAS_I32 n,EAS_I32 * pBytesRead)306 EAS_RESULT EAS_HWReadFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *pBuffer, EAS_I32 n, EAS_I32 *pBytesRead)
307 {
308     EAS_RESULT result;
309     EAS_I32 temp;
310     EAS_U8 *p = pBuffer;
311     EAS_I32 bytesLeft = n;
312 
313     *pBytesRead = 0;
314 
315     /* check handle integrity */
316     if (file->pFile == NULL)
317         return EAS_ERROR_INVALID_HANDLE;
318 
319 #ifdef DEBUG_FILE_IO
320     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWReadFile: Reading %d bytes from position %d\n", n, file->filePos);
321 #endif
322 
323     /* try to fulfill request from buffer */
324     for (;bytesLeft > 0;)
325     {
326         /* how many bytes can we get from buffer? */
327         temp = file->bytesInBuffer - file->readIndex;
328         if (temp > bytesLeft)
329             temp = bytesLeft;
330 
331         /* copy data from buffer */
332         EAS_HWMemCpy(p, &file->buffer[file->readIndex], temp);
333         *pBytesRead += temp;
334         file->readIndex += temp;
335         file->filePos += temp;
336         bytesLeft -= temp;
337         p += temp;
338 
339         /* don't refill buffer if request is bigger than buffer */
340         if ((bytesLeft == 0) || (bytesLeft >= EAS_FILE_BUFFER_SIZE))
341             break;
342 
343         /* refill buffer */
344         if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
345             return result;
346     }
347 
348     /* more to read? do unbuffered read directly to target memory */
349     if (bytesLeft)
350     {
351 
352         /* position the file pointer */
353         if (fseek(file->pFile, file->filePos, SEEK_SET) != 0)
354             return EAS_ERROR_FILE_SEEK;
355 
356         /* read data in the buffer */
357         /*lint -e{826} lint doesn't like this with STATIC_MEMORY defined for some reason */
358         temp = (EAS_I32) fread(p, 1, (size_t) bytesLeft, file->pFile);
359         *pBytesRead += temp;
360         file->filePos += temp;
361 
362         /* reset buffer info */
363         file->bytesInBuffer = 0;
364         file->readIndex = 0;
365     }
366 
367 #ifdef DEBUG_FILE_IO
368     {
369 #define BYTES_PER_LINE 16
370         char str[BYTES_PER_LINE * 3 + 1];
371         EAS_INT i;
372         for (i = 0; i < (n > BYTES_PER_LINE ? BYTES_PER_LINE : n) ; i ++)
373             sprintf(&str[i*3], "%02x ", ((EAS_U8*)pBuffer)[i]);
374         if (i)
375             EAS_ReportX(_EAS_SEVERITY_NOFILTER, "%s\n", str);
376     }
377 #endif
378 
379     /* were n bytes read? */
380     if (*pBytesRead != n)
381         return EAS_EOF;
382 
383     return EAS_SUCCESS;
384 }
385 
386 /*----------------------------------------------------------------------------
387  *
388  * EAS_HWGetByte
389  *
390  * Read a byte from a file
391  *----------------------------------------------------------------------------
392 */
393 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWGetByte(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,void * p)394 EAS_RESULT EAS_HWGetByte (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p)
395 {
396     EAS_RESULT result;
397 
398     /* check handle integrity */
399     if (file->pFile == NULL)
400         return EAS_ERROR_INVALID_HANDLE;
401 
402     /* use local buffer - do we have any data? */
403     if (file->readIndex >= file->bytesInBuffer)
404     {
405         if ((result = EAS_HWFillBuffer(hwInstData, file)) != EAS_SUCCESS)
406             return result;
407 
408         /* if nothing to read, return EOF */
409         if (file->bytesInBuffer == 0)
410             return EAS_EOF;
411     }
412 
413     /* get a character from the buffer */
414     *((EAS_U8*) p) = file->buffer[file->readIndex++];
415 
416 #ifdef DEBUG_FILE_IO
417     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetByte: Reading from position %d, byte = 0x%02x\n", file->filePos, *(EAS_U8*)p);
418 #endif
419 
420     file->filePos++;
421     return EAS_SUCCESS;
422 }
423 
424 /*----------------------------------------------------------------------------
425  *
426  * EAS_HWGetWord
427  *
428  * Read a 16-bit value from the file
429  *----------------------------------------------------------------------------
430 */
EAS_HWGetWord(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,void * p,EAS_BOOL msbFirst)431 EAS_RESULT EAS_HWGetWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
432 {
433     EAS_RESULT result;
434     EAS_I32 count;
435     EAS_U8 c[2];
436 
437 #ifdef DEBUG_FILE_IO
438     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetWord: Reading 2 bytes from position %d\n", file->filePos);
439 #endif
440 
441     /* read 2 bytes from the file */
442     if ((result = EAS_HWReadFile(hwInstData, file, c, 2, &count)) != EAS_SUCCESS)
443         return result;
444 
445     /* order them as requested */
446     if (msbFirst)
447         *((EAS_U16*) p) = ((EAS_U16) c[0] << 8) | c[1];
448     else
449         *((EAS_U16*) p) = ((EAS_U16) c[1] << 8) | c[0];
450 
451     return EAS_SUCCESS;
452 }
453 
454 /*----------------------------------------------------------------------------
455  *
456  * EAS_HWGetDWord
457  *
458  * Read a 16-bit value from the file
459  *----------------------------------------------------------------------------
460 */
EAS_HWGetDWord(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,void * p,EAS_BOOL msbFirst)461 EAS_RESULT EAS_HWGetDWord (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, void *p, EAS_BOOL msbFirst)
462 {
463     EAS_RESULT result;
464     EAS_I32 count;
465     EAS_U8 c[4];
466 
467 #ifdef DEBUG_FILE_IO
468     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWGetDWord: Reading 4 bytes from position %d\n", file->filePos);
469 #endif
470 
471     /* read 4 bytes from the file */
472     if ((result = EAS_HWReadFile(hwInstData, file, c, 4, &count)) != EAS_SUCCESS)
473         return result;
474 
475     /* order them as requested */
476     if (msbFirst)
477         *((EAS_U32*) p) = ((EAS_U32) c[0] << 24) | ((EAS_U32) c[1] << 16) | ((EAS_U32) c[2] << 8) | c[3];
478     else
479         *((EAS_U32*) p) = ((EAS_U32) c[3] << 24) | ((EAS_U32) c[2] << 16) | ((EAS_U32) c[1] << 8) | c[0];
480 
481     return EAS_SUCCESS;
482 }
483 
484 /*----------------------------------------------------------------------------
485  *
486  * EAS_HWFilePos
487  *
488  * Returns the current location in the file
489  *
490  *----------------------------------------------------------------------------
491 */
492 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWFilePos(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,EAS_I32 * pPosition)493 EAS_RESULT EAS_HWFilePos (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pPosition)
494 {
495 
496     /* check handle integrity */
497     if (file->pFile == NULL)
498         return EAS_ERROR_INVALID_HANDLE;
499 
500     *pPosition = file->filePos;
501     return EAS_SUCCESS;
502 }
503 
504 /*----------------------------------------------------------------------------
505  *
506  * EAS_HWFileSeek
507  *
508  * Seek to a specific location in the file
509  *
510  *----------------------------------------------------------------------------
511 */
512 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWFileSeek(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,EAS_I32 position)513 EAS_RESULT EAS_HWFileSeek (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
514 {
515     EAS_I32 newIndex;
516 
517     /* check handle integrity */
518     if (file->pFile == NULL)
519         return EAS_ERROR_INVALID_HANDLE;
520 
521 #ifdef DEBUG_FILE_IO
522     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeek: Seeking to new position %d\n", file->filePos);
523 #endif
524 
525     /* is new position in current buffer? */
526     newIndex = position - file->filePos + file->readIndex;
527     if ((newIndex >= 0) && (newIndex < file->bytesInBuffer))
528     {
529         file->readIndex = newIndex;
530         file->filePos = position;
531         return EAS_SUCCESS;
532     }
533 
534     /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
535     file->filePos = position;
536     file->bytesInBuffer = 0;
537     file->readIndex = 0;
538     return EAS_SUCCESS;
539 }
540 
541 /*----------------------------------------------------------------------------
542  *
543  * EAS_HWFileSeekOfs
544  *
545  * Seek forward or back relative to the current position
546  *
547  *----------------------------------------------------------------------------
548 */
549 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWFileSeekOfs(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,EAS_I32 position)550 EAS_RESULT EAS_HWFileSeekOfs (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 position)
551 {
552     EAS_I32 temp;
553 
554 #ifdef DEBUG_FILE_IO
555     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "EAS_HWFileSeekOfs: Seeking to new position %d\n", file->filePos + position);
556 #endif
557 
558     /* check handle integrity */
559     if (file->pFile == NULL)
560         return EAS_ERROR_INVALID_HANDLE;
561 
562     /* is new position in current buffer? */
563     temp = position + file->readIndex;
564     if ((temp >= 0) && (temp < file->bytesInBuffer))
565     {
566         file->readIndex = temp;
567         file->filePos += position;
568         return EAS_SUCCESS;
569     }
570 
571     /* save new position and reset buffer info so EAS_HWGetByte doesn't fail */
572     file->filePos += position;
573     file->bytesInBuffer = 0;
574     file->readIndex = 0;
575     return EAS_SUCCESS;
576 }
577 
578 /*----------------------------------------------------------------------------
579  *
580  * EAS_HWFileLength
581  *
582  * Return the file length
583  *
584  *----------------------------------------------------------------------------
585 */
586 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWFileLength(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,EAS_I32 * pLength)587 EAS_RESULT EAS_HWFileLength (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_I32 *pLength)
588 {
589     long pos;
590 
591     /* check handle integrity */
592     if (file->pFile == NULL)
593         return EAS_ERROR_INVALID_HANDLE;
594 
595     if ((pos = ftell(file->pFile)) == -1L)
596         return EAS_ERROR_FILE_LENGTH;
597     if (fseek(file->pFile, 0L, SEEK_END) != 0)
598         return EAS_ERROR_FILE_LENGTH;
599     if ((*pLength = ftell(file->pFile)) == -1L)
600         return EAS_ERROR_FILE_LENGTH;
601     if (fseek(file->pFile, pos, SEEK_SET) != 0)
602         return EAS_ERROR_FILE_LENGTH;
603     return EAS_SUCCESS;
604 }
605 
606 /*----------------------------------------------------------------------------
607  *
608  * EAS_HWDupHandle
609  *
610  * Duplicate a file handle
611  *
612  *----------------------------------------------------------------------------
613 */
EAS_HWDupHandle(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file,EAS_FILE_HANDLE * pDupFile)614 EAS_RESULT EAS_HWDupHandle (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file, EAS_FILE_HANDLE* pDupFile)
615 {
616     EAS_HW_FILE *dupfile;
617     int i;
618 
619     /* check handle integrity */
620     *pDupFile = NULL;
621     if (file->pFile == NULL)
622         return EAS_ERROR_INVALID_HANDLE;
623 
624     /* find an empty entry in the file table */
625     dupfile = hwInstData->files;
626     for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
627     {
628         /* is this slot being used? */
629         if (dupfile->pFile == NULL)
630         {
631 
632             /* copy info from the handle to be duplicated */
633             dupfile->filePos = file->filePos;
634             dupfile->pFile = file->pFile;
635 
636             /* set the duplicate handle flag */
637             dupfile->dup = file->dup = EAS_TRUE;
638 
639             /* initialize some values */
640             dupfile->bytesInBuffer = 0;
641             dupfile->readIndex = 0;
642 
643             *pDupFile = dupfile;
644             return EAS_SUCCESS;
645         }
646         dupfile++;
647     }
648 
649     /* too many open files */
650     return EAS_ERROR_MAX_FILES_OPEN;
651 }
652 
653 /*----------------------------------------------------------------------------
654  *
655  * EAS_HWClose
656  *
657  * Wrapper for fclose function
658  *
659  *----------------------------------------------------------------------------
660 */
EAS_HWCloseFile(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE file1)661 EAS_RESULT EAS_HWCloseFile (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE file1)
662 {
663     EAS_HW_FILE *file2,*dupFile;
664     int i;
665 
666     /* check handle integrity */
667     if (file1->pFile == NULL)
668         return EAS_ERROR_INVALID_HANDLE;
669 
670     /* check for duplicate handle */
671     if (file1->dup)
672     {
673         dupFile = NULL;
674         file2 = hwInstData->files;
675         for (i = 0; i < EAS_MAX_FILE_HANDLES; i++)
676         {
677             /* check for duplicate */
678             if ((file1 != file2) && (file2->pFile == file1->pFile))
679             {
680                 /* is there more than one duplicate? */
681                 if (dupFile != NULL)
682                 {
683                     /* clear this entry and return */
684                     file1->pFile = NULL;
685                     return EAS_SUCCESS;
686                 }
687 
688                 /* this is the first duplicate found */
689                 dupFile = file2;
690             }
691             file2++;
692         }
693 
694         /* there is only one duplicate, clear the dup flag */
695         if (dupFile)
696             dupFile->dup = EAS_FALSE;
697         else
698             /* if we get here, there's a serious problem */
699             return EAS_ERROR_HANDLE_INTEGRITY;
700 
701         /* clear this entry and return */
702         file1->pFile = NULL;
703         return EAS_SUCCESS;
704     }
705 
706     /* no duplicates - close the file */
707     if (fclose(file1->pFile) != 0)
708         return EAS_ERROR_CLOSE_FAILED;
709 
710     /* clear this entry and return */
711     file1->pFile = NULL;
712     return EAS_SUCCESS;
713 }
714 
715 /*----------------------------------------------------------------------------
716  *
717  * EAS_HWVibrate
718  *
719  * Turn on/off vibrate function
720  *
721  *----------------------------------------------------------------------------
722 */
723 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWVibrate(EAS_HW_DATA_HANDLE hwInstData,EAS_BOOL state)724 EAS_RESULT EAS_HWVibrate (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
725 {
726     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Vibrate state: %d\n", state);
727     return EAS_SUCCESS;
728 }
729 
730 /*----------------------------------------------------------------------------
731  *
732  * EAS_HWLED
733  *
734  * Turn on/off LED
735  *
736  *----------------------------------------------------------------------------
737 */
738 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWLED(EAS_HW_DATA_HANDLE hwInstData,EAS_BOOL state)739 EAS_RESULT EAS_HWLED (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
740 {
741     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "LED state: %d\n", state);
742     return EAS_SUCCESS;
743 }
744 
745 /*----------------------------------------------------------------------------
746  *
747  * EAS_HWBackLight
748  *
749  * Turn on/off backlight
750  *
751  *----------------------------------------------------------------------------
752 */
753 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWBackLight(EAS_HW_DATA_HANDLE hwInstData,EAS_BOOL state)754 EAS_RESULT EAS_HWBackLight (EAS_HW_DATA_HANDLE hwInstData, EAS_BOOL state)
755 {
756     EAS_ReportX(_EAS_SEVERITY_NOFILTER, "Backlight state: %d\n", state);
757     return EAS_SUCCESS;
758 }
759 
760 /*----------------------------------------------------------------------------
761  *
762  * EAS_HWYield
763  *
764  * This function is called periodically by the EAS library to give the
765  * host an opportunity to allow other tasks to run. There are two ways to
766  * use this call:
767  *
768  * If you have a multi-tasking OS, you can call the yield function in the
769  * OS to allow other tasks to run. In this case, return EAS_FALSE to tell
770  * the EAS library to continue processing when control returns from this
771  * function.
772  *
773  * If tasks run in a single thread by sequential function calls (sometimes
774  * call a "commutator loop"), return EAS_TRUE to cause the EAS Library to
775  * return to the caller. Be sure to check the number of bytes rendered
776  * before passing the audio buffer to the codec - it may not be filled.
777  * The next call to EAS_Render will continue processing until the buffer
778  * has been filled.
779  *
780  *----------------------------------------------------------------------------
781 */
782 /*lint -esym(715, hwInstData) hwInstData available for customer use */
EAS_HWYield(EAS_HW_DATA_HANDLE hwInstData)783 EAS_BOOL EAS_HWYield (EAS_HW_DATA_HANDLE hwInstData)
784 {
785     /* put your code here */
786     return EAS_FALSE;
787 }
788