LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_memory.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
55 #include "lms2012.h"
56 #include "c_memory.h"
57 
58 #if (HARDWARE != SIMULATION)
59  #include <stdlib.h>
60  #include <string.h>
61  #include <stdio.h>
62  #include <unistd.h>
63  #include <dirent.h>
64  #include <sys/stat.h>
65  #include <sys/statvfs.h>
66  #include <dirent.h>
67  #include <sys/types.h>
68  #include <fcntl.h>
69  #include <sys/sysinfo.h>
70  #include <mntent.h>
71 
73 
74 #else
75  #define snprintf _snprintf
76  #include <stdio.h>
77  #include <stdlib.h>
78 
80 
82  {
83  gMemoryInstance= _Instance;
84  }
85 
87  {
88  return gMemoryInstance;
89  }
90 
91 #endif
92 
93 #ifdef DEBUG_C_MEMORY
94 #define DEBUG
95 #define DEBUG_C_MEMORY_LOG
96 #define DEBUG_C_MEMORY_FILE
97 #endif
98 
99 #ifdef DEBUG
100 #define DUBUG_TRACE_FILENAME
101 #endif
102 
103 
104 void cMemoryGetUsage(DATA32 *pTotal,DATA32 *pFree,DATA8 Force)
105 {
106  ULONG Time;
107 #ifndef Linux_X86
108  DATA32 Used;
109  struct statvfs Status;
110 #endif
111 
113 
114  if ((Time >= UPDATE_MEMORY) || (VMInstance.MemoryTimer == 0) || (Force))
115  { // Update values
116 
117  VMInstance.MemoryTimer += Time;
118 
119 #ifndef Linux_X86
120  if (statvfs(MEMORY_FOLDER,&Status) == 0)
121  {
122  VMInstance.MemorySize = INSTALLED_MEMORY;
123  Used = (DATA32)((((Status.f_blocks - Status.f_bavail) * Status.f_bsize) + (KB - 1)) / KB);
124  VMInstance.MemoryFree = INSTALLED_MEMORY - Used;
125  }
126 #else
127  VMInstance.MemorySize = INSTALLED_MEMORY;
128  VMInstance.MemoryFree = INSTALLED_MEMORY;
129 #endif
130 #ifdef DEBUG_C_MEMORY_LOW
131  VMInstance.MemoryFree -= 4400;
132 #endif
133  }
134 
135  *pTotal = VMInstance.MemorySize;
136  *pFree = VMInstance.MemoryFree;
137 }
138 
139 
140 RESULT cMemoryMalloc(void **ppMemory,DATA32 Size)
141 {
142  RESULT Result = FAIL;
143  DATA32 Total;
144  DATA32 Free;
145 
146  cMemoryGetUsage(&Total,&Free,0);
147  if (((Size + (KB - 1)) / KB) < (Free - RESERVED_MEMORY))
148  {
149  *ppMemory = malloc((size_t)Size);
150  if (*ppMemory != NULL)
151  {
152  Result = OK;
153  }
154  }
155 
156  return (Result);
157 }
158 
159 
160 RESULT cMemoryRealloc(void *pOldMemory,void **ppMemory,DATA32 Size)
161 {
162  RESULT Result = FAIL;
163 
164  *ppMemory = realloc(pOldMemory,(size_t)Size);
165  if (*ppMemory != NULL)
166  {
167  Result = OK;
168  }
169 
170  return (Result);
171 }
172 
173 
174 RESULT cMemoryAlloc(PRGID PrgId,DATA8 Type,GBINDEX Size,void **pMemory,HANDLER *pHandle)
175 {
176  RESULT Result = FAIL;
177  HANDLER TmpHandle;
178 
179  *pHandle = -1;
180 
181  if ((PrgId < MAX_PROGRAMS) && (Size > 0) && (Size <= MAX_ARRAY_SIZE))
182  {
183  TmpHandle = 0;
184 
185  while ((TmpHandle < MAX_HANDLES) && (MemoryInstance.pPoolList[PrgId][TmpHandle].pPool != NULL))
186  {
187  TmpHandle++;
188  }
189  if (TmpHandle < MAX_HANDLES)
190  {
191 
192  if (cMemoryMalloc(&MemoryInstance.pPoolList[PrgId][TmpHandle].pPool,(DATA32)Size) == OK)
193  {
194  *pMemory = MemoryInstance.pPoolList[PrgId][TmpHandle].pPool;
195  MemoryInstance.pPoolList[PrgId][TmpHandle].Type = Type;
196  MemoryInstance.pPoolList[PrgId][TmpHandle].Size = Size;
197  *pHandle = TmpHandle;
198  Result = OK;
199 #ifdef DEBUG
200  printf(" Malloc P=%1u H=%1u T=%1u S=%8lu A=%8p\r\n",(unsigned int)PrgId,(unsigned int)TmpHandle,(unsigned int)Type,(unsigned long)Size,MemoryInstance.pPoolList[PrgId][TmpHandle].pPool);
201 #endif
202  }
203  }
204  }
205 #ifdef DEBUG
206  if (Result != OK)
207  {
208  printf(" Malloc error P=%1u S=%8lu\r\n",(unsigned int)PrgId,(unsigned long)Size);
209  }
210 #endif
211 
212  return (Result);
213 }
214 
215 
216 void* cMemoryReallocate(PRGID PrgId,HANDLER Handle,GBINDEX Size)
217 {
218  void *pTmp;
219 
220  pTmp = NULL;
221  if ((PrgId < MAX_PROGRAMS) && (Handle >= 0) && (Handle < MAX_HANDLES))
222  {
223  if ((Size > 0) && (Size <= MAX_ARRAY_SIZE))
224  {
225  if (cMemoryRealloc(MemoryInstance.pPoolList[PrgId][Handle].pPool,&pTmp,(DATA32)Size) == OK)
226  {
227  MemoryInstance.pPoolList[PrgId][Handle].pPool = pTmp;
228  MemoryInstance.pPoolList[PrgId][Handle].Size = Size;
229  }
230  else
231  {
232  pTmp = NULL;
233  printf("cMemoryReallocate out of memory\r\n");
234  }
235  }
236  }
237 #ifdef DEBUG
238  if (pTmp != NULL)
239  {
240  printf(" Reallocate P=%1u H=%1u S=%8lu A=%8p\r\n",(unsigned int)PrgId,(unsigned int)Handle,(unsigned long)Size,MemoryInstance.pPoolList[PrgId][Handle].pPool);
241  }
242  else
243  {
244  printf(" Reallocate error P=%1u H=%1u S=%8lu\r\n",(unsigned int)PrgId,(unsigned int)Handle,(unsigned long)Size);
245  }
246 #endif
247 
248  return (pTmp);
249 }
250 
251 
252 RESULT cMemoryGetPointer(PRGID PrgId,HANDLER Handle,void **pMemory)
253 {
254  RESULT Result = FAIL;
255 
256  *pMemory = NULL;
257 
258  if ((PrgId < MAX_PROGRAMS) && (Handle >= 0) && (Handle < MAX_HANDLES))
259  {
260  if (MemoryInstance.pPoolList[PrgId][Handle].pPool != NULL)
261  {
262  *pMemory = MemoryInstance.pPoolList[PrgId][Handle].pPool;
263  Result = OK;
264  }
265  }
266 #ifdef DEBUG
267  if (Result != OK)
268  {
269  printf(" Get pointer error P=%1u H=%1u\r\n",(unsigned int)PrgId,(unsigned int)Handle);
270  }
271 #endif
272 
273  return (Result);
274 }
275 
276 
277 RESULT cMemoryArraryPointer(PRGID PrgId,HANDLER Handle,void **pMemory)
278 {
279  RESULT Result = FAIL;
280  void *pTmp;
281 
282  if (cMemoryGetPointer(PrgId,Handle,&pTmp) == OK)
283  {
284  *pMemory = (*(DESCR*)pTmp).pArray;
285  Result = OK;
286  }
287 
288  return (Result);
289 }
290 
291 
293 {
294  DSPSTAT Result = FAILBREAK;
295  FDESCR *pFDescr;
296 
297  if ((PrgId < MAX_PROGRAMS) && (Handle >= 0) && (Handle < MAX_HANDLES))
298  {
299  if (MemoryInstance.pPoolList[PrgId][Handle].pPool != NULL)
300  {
301  if (MemoryInstance.pPoolList[PrgId][Handle].Type == POOL_TYPE_FILE)
302  {
303  pFDescr = (FDESCR*)MemoryInstance.pPoolList[PrgId][Handle].pPool;
304  if (((*pFDescr).Access))
305  {
306  (*pFDescr).Access = 0;
307  close((*pFDescr).hFile);
308  sync();
309  Result = NOBREAK;
310  }
311 #ifdef DEBUG
312  printf(" Close file %d\r\n",(*pFDescr).hFile);
313 #endif
314  }
315  else
316  {
317  Result = NOBREAK;
318  }
319 
320 #ifdef DEBUG
321  printf(" Free P=%1u H=%1u T=%1u S=%8lu A=%8p\r\n",(unsigned int)PrgId,(unsigned int)Handle,(unsigned int)MemoryInstance.pPoolList[PrgId][Handle].Type,(unsigned long)MemoryInstance.pPoolList[PrgId][Handle].Size,MemoryInstance.pPoolList[PrgId][Handle].pPool);
322 #endif
323  free(MemoryInstance.pPoolList[PrgId][Handle].pPool);
324  MemoryInstance.pPoolList[PrgId][Handle].pPool = NULL;
325  MemoryInstance.pPoolList[PrgId][Handle].Size = 0;
326 
327  }
328  }
329 
330  return (Result);
331 }
332 
333 
334 void cMemoryFreePool(PRGID PrgId,void *pMemory)
335 {
336  HANDLER TmpHandle;
337 
338  TmpHandle = 0;
339  while ((TmpHandle < MAX_HANDLES) && (MemoryInstance.pPoolList[PrgId][TmpHandle].pPool != pMemory))
340  {
341  TmpHandle++;
342  }
343  if (TmpHandle < MAX_HANDLES)
344  {
345  cMemoryFreeHandle(PrgId,TmpHandle);
346  }
347 }
348 
349 
351 {
352  HANDLER TmpHandle;
353 
354  for (TmpHandle = 0;TmpHandle < MAX_HANDLES;TmpHandle++)
355  {
356  cMemoryFreeHandle(PrgId,TmpHandle);
357  }
358 
359  // Ensure that path is emptied
360  MemoryInstance.PathList[PrgId][0] = 0;
361 }
362 
363 
364 void cMemoryFreeAll(void)
365 {
366  PRGID TmpPrgId;
367 
368  for (TmpPrgId = 0;TmpPrgId < MAX_PROGRAMS;TmpPrgId++)
369  {
370  cMemoryFreeProgram(TmpPrgId);
371  }
372 }
373 
374 
375 RESULT cMemoryInit(void)
376 {
377  RESULT Result = FAIL;
378  DATA8 Tmp;
379  PRGID TmpPrgId;
380  HANDLER TmpHandle;
381  int File;
382  char PrgNameBuf[vmFILENAMESIZE];
383 
384  snprintf(PrgNameBuf,vmFILENAMESIZE,"%s/%s%s",vmSETTINGS_DIR,vmLASTRUN_FILE_NAME,vmEXT_CONFIG);
385  File = open(PrgNameBuf,O_RDONLY);
386  if (File >= MIN_HANDLE)
387  {
388  if (read(File,MemoryInstance.Cache,sizeof(MemoryInstance.Cache)) != sizeof(MemoryInstance.Cache))
389  {
390  close (File);
391  File = -1;
392  }
393  else
394  {
395  close (File);
396  }
397  }
398  if (File < 0)
399  {
400  for (Tmp = 0;Tmp < CACHE_DEEPT;Tmp++)
401  {
402  MemoryInstance.Cache[Tmp][0] = 0;
403  }
404  }
405 
406  for (TmpPrgId = 0;TmpPrgId < MAX_PROGRAMS;TmpPrgId++)
407  {
408  for (TmpHandle = 0;TmpHandle < MAX_HANDLES;TmpHandle++)
409  {
410  MemoryInstance.pPoolList[TmpPrgId][TmpHandle].pPool = NULL;
411  }
412  }
413 
414  VMInstance.MemorySize = INSTALLED_MEMORY;
415  VMInstance.MemoryFree = INSTALLED_MEMORY;
416 
417  MemoryInstance.SyncTime = (DATA32)0;
418  MemoryInstance.SyncTick = (DATA32)0;
419 
420  Result = OK;
421 
422  return (Result);
423 }
424 
425 
426 RESULT cMemoryOpen(PRGID PrgId,GBINDEX Size,void **pMemory)
427 {
428  RESULT Result = FAIL;
429  HANDLER TmpHandle;
430 
431  Result = cMemoryAlloc(PrgId,POOL_TYPE_MEMORY,Size,pMemory,&TmpHandle);
432 
433  return (Result);
434 }
435 
436 
437 RESULT cMemoryClose(PRGID PrgId)
438 {
439  RESULT Result = FAIL;
440 
441  cMemoryFreeProgram(PrgId);
442  Result = OK;
443 
444  return (Result);
445 }
446 
447 
448 RESULT cMemoryExit(void)
449 {
450  RESULT Result = FAIL;
451  int File;
452  char PrgNameBuf[vmFILENAMESIZE];
453 
454  snprintf(PrgNameBuf,vmFILENAMESIZE,"%s/%s%s",vmSETTINGS_DIR,vmLASTRUN_FILE_NAME,vmEXT_CONFIG);
455  File = open(PrgNameBuf,O_CREAT | O_WRONLY | O_TRUNC,FILEPERMISSIONS);
456  if (File >= MIN_HANDLE)
457  {
458  write(File,MemoryInstance.Cache,sizeof(MemoryInstance.Cache));
459  close (File);
460  }
461 
462  Result = OK;
463 
464  return (Result);
465 }
466 
467 
468 void* cMemoryResize(PRGID PrgId,HANDLER TmpHandle,DATA32 Elements)
469 {
470  DATA32 Size;
471  void *pTmp = NULL;
472 
473 
474  if (cMemoryGetPointer(PrgId,TmpHandle,&pTmp) == OK)
475  {
476  Size = Elements * (*(DESCR*)pTmp).ElementSize + sizeof(DESCR);
477  pTmp = cMemoryReallocate(PrgId,TmpHandle,(GBINDEX)Size);
478  if (pTmp != NULL)
479  {
480  (*(DESCR*)pTmp).Elements = Elements;
481  }
482 
483 #ifdef DEBUG
484  printf(" Resize P=%1u H=%1u T=%1u S=%8lu A=%8p\r\n",(unsigned int)PrgId,(unsigned int)TmpHandle,(unsigned int)MemoryInstance.pPoolList[PrgId][TmpHandle].Type,(unsigned long)MemoryInstance.pPoolList[PrgId][TmpHandle].Size,MemoryInstance.pPoolList[PrgId][TmpHandle].pPool);
485 #endif
486  }
487  if (pTmp != NULL)
488  {
489  pTmp = (*(DESCR*)pTmp).pArray;
490  }
491 
492  return (pTmp);
493 }
494 
495 
496 void FindName(char *pSource,char *pPath,char *pName,char *pExt)
497 {
498  int Source = 0;
499  int Destination = 0;
500 
501  while (pSource[Source])
502  {
503  Source++;
504  }
505  while ((Source > 0) && (pSource[Source] != '/'))
506  {
507  Source--;
508  }
509  if (pSource[Source] == '/')
510  {
511  if (pPath != NULL)
512  {
513  for (Destination = 0;Destination <= Source;Destination++)
514  {
515  pPath[Destination] = pSource[Destination];
516  }
517  }
518  Source++;
519  }
520  if (pPath != NULL)
521  {
522  pPath[Destination] = 0;
523  }
524  Destination = 0;
525  while ((pSource[Source]) && (pSource[Source] != '.'))
526  {
527  if (pName != NULL)
528  {
529  pName[Destination] = pSource[Source];
530  Destination++;
531  }
532  Source++;
533  }
534  if (pName != NULL)
535  {
536  pName[Destination] = 0;
537  }
538  if (pExt != NULL)
539  {
540  Destination = 0;
541  while (pSource[Source])
542  {
543  pExt[Destination] = pSource[Source];
544  Source++;
545  Destination++;
546  }
547  pExt[Destination] = 0;
548  }
549 }
550 
551 
552 RESULT cMemoryCheckFilename(char *pFilename,char *pPath,char *pName,char *pExt)
553 {
554  RESULT Result = FAIL;
555  char Path[vmFILENAMESIZE];
556  char Name[vmFILENAMESIZE];
557  char Ext[vmFILENAMESIZE];
558 
559 #ifndef DISABLE_FILENAME_CHECK
560 
561  if (strlen(pFilename) < vmFILENAMESIZE)
562  {
563  if (ValidateString((DATA8*)pFilename,vmCHARSET_FILENAME) == OK)
564  {
565  FindName(pFilename,Path,Name,Ext);
566  if (strlen(Path) < vmPATHSIZE)
567  {
568  if (pPath != NULL)
569  {
570  strcpy(pPath,Path);
571  }
572  if (strlen(Name) < vmNAMESIZE)
573  {
574  if (pName != NULL)
575  {
576  strcpy(pName,Name);
577  }
578  if (strlen(Ext) < vmEXTSIZE)
579  {
580  if (pExt != NULL)
581  {
582  strcpy(pExt,Ext);
583  }
584  Result = OK;
585  }
586  }
587  }
588  }
589  }
590 #else
591  if (strlen(pFilename) < vmFILENAMESIZE)
592  {
593  FindName(pFilename,Path,Name,Ext);
594  if (strlen(Path) < vmPATHSIZE)
595  {
596  if (pPath != NULL)
597  {
598  strcpy(pPath,Path);
599  }
600  if (strlen(Name) < vmNAMESIZE)
601  {
602  if (pName != NULL)
603  {
604  strcpy(pName,Name);
605  }
606  if (strlen(Ext) < vmEXTSIZE)
607  {
608  if (pExt != NULL)
609  {
610  strcpy(pExt,Ext);
611  }
612  Result = OK;
613  }
614  }
615  }
616  }
617 #endif
618  if (Result != OK)
619  {
620 #ifdef DEBUG_TRACE_FILENAME
621  printf("Filename error in [%s]\r\n",pFilename);
622 #endif
624  {
626  }
627  }
628 
629  return (Result);
630 }
631 
632 
633 RESULT ConstructFilename(PRGID PrgId,char *pFilename,char *pName,char *pDefaultExt)
634 {
635  RESULT Result = FAIL;
636  char Path[vmPATHSIZE];
637  char Name[vmNAMESIZE];
638  char Ext[vmEXTSIZE];
639 
640  Result = cMemoryCheckFilename(pFilename,Path,Name,Ext);
641 
642  if (Result == OK)
643  { // Filename OK
644 
645  if (Path[0] == 0)
646  { // Default path
647 
648  snprintf(Path,vmPATHSIZE,"%s",(char*)MemoryInstance.PathList[PrgId]);
649  }
650 
651  if (Ext[0] == 0)
652  { // Default extension
653 
654  snprintf(Ext,vmEXTSIZE,"%s",pDefaultExt);
655  }
656 
657  // Construct filename for open
658  snprintf(pName,vmFILENAMESIZE,"%s%s%s",Path,Name,Ext);
659 
660 #ifdef DEBUG_TRACE_FILENAME
661  printf("c_memory ConstructFilename: [%s]\r\n",pName);
662 #endif
663 
664  }
665 
666  return (Result);
667 }
668 
669 
670 int FindDot(char *pString)
671 {
672  int Result = -1;
673  int Pointer = 0;
674 
675  while (pString[Pointer])
676  {
677  if (pString[Pointer] == '.')
678  {
679  Result = Pointer;
680  }
681  Pointer++;
682  }
683 
684  return (Result);
685 }
686 
687 void cMemoryDeleteCacheFile(char *pFileName)
688 {
689  DATA8 Item;
690  DATA8 Tmp;
691 
692 #ifdef DEBUG
693  printf("DEL_CACHE_FILE %s\r\n",(char*)pFileName);
694 #endif
695 
696  Item = 0;
697  Tmp = 0;
698 
699  while ((Item < CACHE_DEEPT) && (Tmp == 0))
700  {
701  if (strcmp((char*)MemoryInstance.Cache[Item],(char*)pFileName) == 0)
702  {
703  Tmp = 1;
704  }
705  else
706  {
707  Item++;
708  }
709  }
710  while (Item < (CACHE_DEEPT - 1))
711  {
712  strcpy((char*)MemoryInstance.Cache[Item],(char*)MemoryInstance.Cache[Item + 1]);
713  Item++;
714  }
715  MemoryInstance.Cache[Item][0] = 0;
716 }
717 
718 
719 int cMemorySort(void *ppFirst,void *ppSecond)
720 {
721  int Result;
722  int First,Second;
723  char *pFirst;
724  char *pSecond;
725 
726  pFirst = (char*)(*(const struct dirent **)ppFirst)->d_name;
727  pSecond = (char*)(*(const struct dirent **)ppSecond)->d_name;
728 
729  First = FindDot(pFirst);
730  Second = FindDot(pSecond);
731 
732  if ((First >= 0) && (Second >= 0))
733  {
734  Result = strcmp(&pFirst[First],&pSecond[Second]);
735  if (Result == 0)
736  {
737  Result = strcmp(pFirst,pSecond);
738  }
739  }
740  else
741  {
742  if ((First < 0) && (Second < 0))
743  {
744  Result = strcmp(pFirst,pSecond);
745  }
746  else
747  {
748  if (First < 0)
749  {
750  Result = 1;
751  }
752  else
753  {
754  Result = -1;
755  }
756  }
757  }
758 
759  return (Result);
760 }
761 
762 
763 DATA8 cMemoryFindSubFolders(char *pFolderName)
764 {
765  struct dirent **NameList;
766  int Items;
767  DATA8 Folders = 0;
768 
769 #ifdef Linux_X86
770  Items = scandir(pFolderName,&NameList,0,(int (*)(const struct dirent **,const struct dirent **))cMemorySort);
771 #else
772  Items = scandir(pFolderName,&NameList,0,(int (*)(const void *,const void *))cMemorySort);
773 #endif
774  if (Items >= 0)
775  {
776  while (Items--)
777  {
778  if ((*NameList[Items]).d_name[0] != '.')
779  {
780  if (((*NameList[Items]).d_name[0] != 'C') || ((*NameList[Items]).d_name[1] != 'V') || ((*NameList[Items]).d_name[2] != 'S'))
781  {
782  Folders++;
783  }
784  }
785  free(NameList[Items]);
786  }
787  free(NameList);
788  }
789 
790  return (Folders);
791 }
792 
793 
795 {
796  DATA8 Result = 0;
797 
798  if (pExt[0])
799  {
800  if (strcmp(pExt,EXT_SOUND) == 0)
801  {
802  Result = TYPE_SOUND;
803  }
804  else
805  {
806  if (strcmp(pExt,EXT_GRAPHICS) == 0)
807  {
808  Result = TYPE_GRAPHICS;
809  }
810  else
811  {
812  if (strcmp(pExt,EXT_BYTECODE) == 0)
813  {
814  Result = TYPE_BYTECODE;
815  }
816  else
817  {
818  if (strcmp(pExt,EXT_DATALOG) == 0)
819  {
820  Result = TYPE_DATALOG;
821  }
822  else
823  {
824  if (strcmp(pExt,EXT_PROGRAM) == 0)
825  {
826  Result = TYPE_PROGRAM;
827  }
828  else
829  {
830  if (strcmp(pExt,EXT_TEXT) == 0)
831  {
832  Result = TYPE_TEXT;
833  }
834  else
835  {
836  }
837  }
838  }
839  }
840  }
841  }
842  }
843  else
844  {
845  Result = TYPE_FOLDER;
846  }
847 
848  return (Result);
849 }
850 
851 
852 DATA8 cMemoryGetSubFolderName(DATA8 Item,DATA8 MaxLength,char *pFolderName,char *pSubFolderName)
853 {
854  DATA8 Filetype = 0;
855  struct dirent **NameList;
856  int Items;
857  int Tmp;
858  DATA8 Char;
859  DATA8 Folders = 0;
860 
861  pSubFolderName[0] = 0;
862 #ifdef Linux_X86
863  Items = scandir(pFolderName,&NameList,0,(int (*)(const struct dirent **,const struct dirent **))cMemorySort);
864 #else
865  Items = scandir(pFolderName,&NameList,0,(int (*)(const void *,const void *))cMemorySort);
866 #endif
867  Tmp = 0;
868 
869  if (Items >= 0)
870  {
871  while (Tmp < Items)
872  {
873  if ((*NameList[Tmp]).d_name[0] != '.')
874  {
875  if (((*NameList[Tmp]).d_name[0] != 'C') || ((*NameList[Tmp]).d_name[1] != 'V') || ((*NameList[Tmp]).d_name[2] != 'S'))
876  {
877  Folders++;
878  if (Item == Folders)
879  {
880  Char = 0;
881  while (((*NameList[Tmp]).d_name[Char]) && ((*NameList[Tmp]).d_name[Char] != '.'))
882  {
883  Char++;
884  }
885  if ((*NameList[Tmp]).d_name[Char] == '.')
886  {
887  Filetype = cMemoryFindType(&(*NameList[Tmp]).d_name[Char]);
888 
889  // delete extension
890  (*NameList[Tmp]).d_name[Char] = 0;
891  snprintf((char*)pSubFolderName,(int)MaxLength,"%s",(*NameList[Tmp]).d_name);
892  }
893  else
894  { // must be a folder or file without extension
895  snprintf((char*)pSubFolderName,(int)MaxLength,"%s",(*NameList[Tmp]).d_name);
896  Filetype = TYPE_FOLDER;
897  }
898  }
899  }
900  }
901  free(NameList[Tmp]);
902  Tmp++;
903  }
904  free(NameList);
905  }
906 
907  return (Filetype);
908 }
909 
910 
911 void cMemoryDeleteSubFolders(char *pFolderName)
912 {
913  struct dirent *d;
914  DIR *dir;
915  char buf[256];
916  DATA8 DeleteOk = 1;
917 
918  if (strcmp(pFolderName,DEMO_FILE_NAME) == 0)
919  {
920  DeleteOk = 0;
921  }
922 
923  if (DeleteOk)
924  {
925  dir = opendir(pFolderName);
926 
927  if (dir != NULL)
928  {
929  while((d = readdir(dir)))
930  {
931 #ifdef DEBUG
932  printf("%s\r\n",d->d_name);
933 #endif
934 
935  sprintf(buf, "%s/%s", pFolderName, d->d_name);
936  remove(buf);
938  }
939  closedir(dir);
940  remove(pFolderName);
941  }
942  else
943  {
944  cMemoryDeleteCacheFile(pFolderName);
945  remove(pFolderName);
946  }
947  }
948 }
949 
950 
951 DATA32 cMemoryFindSize(char *pFolderName,DATA32 *pFiles)
952 {
953  struct dirent **NameList;
954  struct stat Status;
955  int Items;
956  DATA32 Size = 0;
957 
958  *pFiles = 0;
959  if (stat(pFolderName,&Status) == 0)
960  {
961  Size += (DATA32)Status.st_size;
962 #ifdef Linux_X86
963  Items = scandir(pFolderName,&NameList,0,(int (*)(const struct dirent **,const struct dirent **))cMemorySort);
964 #else
965  Items = scandir(pFolderName,&NameList,0,(int (*)(const void *,const void *))cMemorySort);
966 #endif
967  if (Items >= 0)
968  {
969  *pFiles = (DATA32)Items;
970 
971  while (Items--)
972  {
973  stat((*NameList[Items]).d_name,&Status);
974  Size += (DATA32)Status.st_size;
975  free(NameList[Items]);
976  }
977  free(NameList);
978  }
979  }
980  Size = (Size + (KB - 1)) / KB;
981 
982  return (Size);
983 }
984 
985 
986 DATA8 cMemoryGetCacheName(DATA8 Item,DATA8 MaxLength,char *pFileName,char *pName)
987 {
988  DATA8 Result = 0;
989  char Path[vmPATHSIZE];
990  char Name[vmNAMESIZE];
991  char Ext[vmEXTSIZE];
992  char Filename[vmFILENAMESIZE];
993 
994  if ((Item > 0) && (Item <= CACHE_DEEPT))
995  {
996  if (MemoryInstance.Cache[Item - 1])
997  {
998  snprintf(Filename,vmFILENAMESIZE,"%s",MemoryInstance.Cache[Item - 1]);
999 
1000  if (cMemoryCheckFilename(Filename,Path,Name,Ext) == OK)
1001  {
1002  snprintf((char*)pFileName,MaxLength,"%s",Filename);
1003  if (MaxLength >= 2)
1004  {
1005  if (strlen(Name) >= MaxLength)
1006  {
1007  Name[MaxLength - 1] = 0;
1008  Name[MaxLength - 2] = 0x7F;
1009  }
1010  snprintf((char*)pName,MaxLength,"%s",Name);
1011  Result = cMemoryFindType(Ext);
1012  }
1013  }
1014  }
1015  }
1016 
1017  return(Result);
1018 }
1019 
1020 
1022 {
1023  DATA8 Result = 0;
1024  DATA8 Tmp;
1025 
1026  for (Tmp = 0;Tmp < CACHE_DEEPT;Tmp++)
1027  {
1028  if (MemoryInstance.Cache[Tmp][0])
1029  {
1030  Result++;
1031  }
1032  }
1033 
1034  return (Result);
1035 }
1036 
1037 
1038 DATA8 cMemoryFindFiles(char *pFolderName)
1039 {
1040  struct dirent **NameList;
1041  int Items;
1042  DATA8 Files = 0;
1043 
1044  Items = scandir(pFolderName,&NameList,0,alphasort);
1045  if (Items >= 0)
1046  {
1047  while (Items--)
1048  {
1049  if ((*NameList[Items]).d_name[0] != '.')
1050  {
1051  if (((*NameList[Items]).d_name[0] != 'C') || ((*NameList[Items]).d_name[1] != 'V') || ((*NameList[Items]).d_name[2] != 'S'))
1052  {
1053  Files++;
1054  }
1055  }
1056  free(NameList[Items]);
1057  }
1058  free(NameList);
1059  }
1060 
1061  return (Files);
1062 }
1063 
1064 
1065 void cMemoryGetResourcePath(PRGID PrgId,char *pString,DATA8 MaxLength)
1066 {
1067  snprintf(pString,MaxLength,"%s",MemoryInstance.PathList[PrgId]);
1068 }
1069 
1070 
1071 RESULT cMemoryGetIcon(DATA8 *pFolderName,DATA8 Item,DATA32 *pImagePointer)
1072 {
1073  RESULT Result = FAIL;
1074 
1075  DATA32 ISize;
1076  IP pImage;
1077  HANDLER TmpHandle;
1078  PRGID TmpPrgId;
1079  char PrgNamePath[SUBFOLDERNAME_SIZE];
1080  char PrgNameBuf[MAX_FILENAME_SIZE];
1081  LFILE *pFile;
1082 
1083  TmpPrgId = CurrentProgramId();
1084 
1085  cMemoryGetSubFolderName(Item,SUBFOLDERNAME_SIZE,(char*)pFolderName,PrgNamePath);
1086 
1087  if (PrgNamePath[0])
1088  {
1089  snprintf(PrgNameBuf,MAX_FILENAME_SIZE,"%s%s/icon%s",(char*)pFolderName,PrgNamePath,EXT_GRAPHICS);
1090 
1091  pFile = fopen (PrgNameBuf, "rb");
1092  if (NULL != pFile)
1093  {
1094  fseek (pFile , 0 , SEEK_END);
1095  ISize = ftell (pFile);
1096  rewind (pFile);
1097 
1098  // allocate memory to contain the whole file:
1099  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pImage,&TmpHandle) == OK)
1100  {
1101  if (ISize == fread(pImage,1,ISize,pFile))
1102  {
1103  *pImagePointer = (DATA32)pImage;
1104  Result = OK;
1105  }
1106  }
1107  fclose (pFile);
1108  }
1109  }
1110 
1111  return (Result);
1112 }
1113 
1114 
1115 void cMemoryFilename(PRGID PrgId,char *pName,char *pExt,DATA8 Length,char *pResult)
1116 {
1117  if ((pName[0] == '.') || (pName[0] == '/') || (pName[0] == '~') || (pName[0] == '\"'))
1118  { // Path to file
1119 
1120  snprintf(pResult,Length,"%s%s",pName,pExt);
1121  }
1122  else
1123  { // Local file
1124 
1125  snprintf(pResult,Length,"%s%s%s",(char*)MemoryInstance.PathList[PrgId],pName,pExt);
1126  }
1127 #ifdef DEBUG
1128  printf("Filename = [%s]\r\n",pResult);
1129 #endif
1130 }
1131 
1132 
1133 static char Delimiter[][3] =
1134 {
1135  [DEL_NONE] = "",
1136  [DEL_TAB] = "\t",
1137  [DEL_SPACE] = " ",
1138  [DEL_RETURN] = "\r",
1139  [DEL_COLON] = ":",
1140  [DEL_COMMA] = ",",
1141  [DEL_LINEFEED] = "\n",
1142  [DEL_CRLF] = "\r\n",
1143 };
1144 
1145 
1146 enum
1147 {
1152 };
1153 
1154 
1155 DSPSTAT cMemoryGetFileHandle(PRGID PrgId,char *pFileName,HANDLER *pHandle,DATA8 *pOpenForWrite)
1156 {
1157  DSPSTAT Result = FAILBREAK;
1158  FDESCR *pFDescr;
1159  HANDLER TmpHandle;
1160 
1161  *pHandle = -1;
1162  *pOpenForWrite = 0;
1163 
1164  TmpHandle = 0;
1165  while ((TmpHandle < MAX_HANDLES) && (*pHandle == -1))
1166  {
1167  if (MemoryInstance.pPoolList[PrgId][TmpHandle].Type == POOL_TYPE_FILE)
1168  {
1169  if (cMemoryGetPointer(PrgId,TmpHandle,(void**)&pFDescr) == OK)
1170  {
1171  if ((*pFDescr).Access)
1172  {
1173  if (strcmp(pFileName,(*pFDescr).Filename) == 0)
1174  {
1175  *pHandle = TmpHandle;
1176  if (((*pFDescr).Access == OPEN_FOR_WRITE) || ((*pFDescr).Access == OPEN_FOR_APPEND) || ((*pFDescr).Access == OPEN_FOR_LOG))
1177  {
1178  *pOpenForWrite = 1;
1179  }
1180 
1181  Result = NOBREAK;
1182 
1183  }
1184  }
1185  }
1186  }
1187  TmpHandle++;
1188  }
1189 
1190 #ifdef DEBUG_C_MEMORY_FILE
1191  printf("Handle for file %5d %s\r\n",*pHandle,pFileName);
1192 #endif
1193  Result = NOBREAK;
1194 
1195  return (Result);
1196 }
1197 
1198 
1199 RESULT cMemoryCheckOpenWrite(char *pFileName)
1200 {
1201  RESULT Result = FAIL;
1202  HANDLER Handle;
1203  DATA8 OpenForWrite;
1204  char FilenameBuf[vmFILENAMESIZE];
1205 
1206  if (ConstructFilename(USER_SLOT,(char*)pFileName,FilenameBuf,"") == OK)
1207  {
1208  cMemoryGetFileHandle(USER_SLOT,FilenameBuf,&Handle,&OpenForWrite);
1209  if (OpenForWrite)
1210  {
1211  Result = OK;
1212  }
1213  }
1214 
1215  return(Result);
1216 }
1217 
1218 
1219 DSPSTAT cMemoryOpenFile(PRGID PrgId,DATA8 Access,char *pFileName,HANDLER *pHandle,DATA32 *pSize)
1220 {
1221  DSPSTAT Result = FAILBREAK;
1222  FDESCR *pFDescr;
1223  struct stat FileStatus;
1224  int hFile = -1;
1225 
1226  *pHandle = 0;
1227  *pSize = 0;
1228 
1229  switch (Access)
1230  {
1231  case OPEN_FOR_WRITE :
1232  {
1233  hFile = open(pFileName,O_CREAT | O_WRONLY | O_TRUNC,FILEPERMISSIONS);
1234  chmod(pFileName,FILEPERMISSIONS);
1235 #ifdef DEBUG_C_MEMORY_FILE
1236  printf("Open for write %5d %s\r\n",hFile,pFileName);
1237 #endif
1238  }
1239  break;
1240 
1241  case OPEN_FOR_APPEND :
1242  {
1243  hFile = open(pFileName,O_CREAT | O_WRONLY | O_APPEND,FILEPERMISSIONS);
1244  chmod(pFileName,FILEPERMISSIONS);
1245 #ifdef DEBUG_C_MEMORY_FILE
1246  printf("Open for append %5d %s\r\n",hFile,pFileName);
1247 #endif
1248  }
1249  break;
1250 
1251  case OPEN_FOR_READ :
1252  {
1253  hFile = open(pFileName,O_RDONLY);
1254  Result = NOBREAK;
1255 #ifdef DEBUG_C_MEMORY_FILE
1256  printf("Open for read %5d %s\r\n",hFile,pFileName);
1257 #endif
1258  }
1259  break;
1260 
1261  case OPEN_FOR_LOG :
1262  {
1263  hFile = open(pFileName,O_CREAT | O_WRONLY | O_APPEND,FILEPERMISSIONS);
1264  chmod(pFileName,FILEPERMISSIONS);
1265 #ifdef DEBUG_C_MEMORY_FILE
1266  printf("Open for append %5d %s\r\n",hFile,pFileName);
1267 #endif
1268  }
1269  break;
1270 
1271  }
1272 
1273  if (hFile >= MIN_HANDLE)
1274  {
1275  if (cMemoryAlloc(PrgId,POOL_TYPE_FILE,(GBINDEX)sizeof(FDESCR),(void**)&pFDescr,pHandle) == OK)
1276  {
1277  (*pFDescr).hFile = hFile;
1278  (*pFDescr).Access = Access;
1279  snprintf((*pFDescr).Filename,MAX_FILENAME_SIZE,"%s",pFileName);
1280 
1281  stat(pFileName,&FileStatus);
1282  *pSize = FileStatus.st_size;
1283 
1284  Result = NOBREAK;
1285  }
1286  else
1287  {
1288  close(hFile);
1289  }
1290  }
1291 
1292  if (Result == FAILBREAK)
1293  {
1295  }
1296 
1297  return (Result);
1298 }
1299 
1300 
1301 DSPSTAT cMemoryWriteFile(PRGID PrgId,HANDLER Handle,DATA32 Size,DATA8 Del,DATA8 *pSource)
1302 {
1303  DSPSTAT Result = FAILBREAK;
1304  FDESCR *pFDescr;
1305 
1306  if (cMemoryGetPointer(PrgId,Handle,(void**)&pFDescr) == OK)
1307  {
1308  if (((*pFDescr).Access == OPEN_FOR_WRITE) || ((*pFDescr).Access == OPEN_FOR_APPEND) || ((*pFDescr).Access == OPEN_FOR_LOG))
1309  {
1310  if (write((*pFDescr).hFile,pSource,Size) == Size)
1311  {
1312 #ifdef DEBUG_C_MEMORY_FILE
1313  printf("Write to %-2d %5d %s [%d]\r\n",Handle,(*pFDescr).hFile,(*pFDescr).Filename,Size);
1314 #endif
1315  if (Del < DELS)
1316  {
1317  if (Del != DEL_NONE)
1318  {
1319  Size = strlen(Delimiter[Del]);
1320  if (write((*pFDescr).hFile,Delimiter[Del],Size) == Size)
1321  {
1322  Result = NOBREAK;
1323  }
1324  }
1325  else
1326  {
1327  Result = NOBREAK;
1328  }
1329  }
1330  }
1331  }
1332  }
1333 
1334  if (Result == FAILBREAK)
1335  {
1337  }
1338 
1339  return (Result);
1340 }
1341 
1342 
1343 DSPSTAT cMemoryReadFile(PRGID PrgId,HANDLER Handle,DATA32 Size,DATA8 Del,DATA8 *pDestination)
1344 {
1345  DSPSTAT Result = FAILBREAK;
1346  FDESCR *pFDescr;
1347  DATA8 No;
1348  DATA8 Tmp;
1349  DATA8 Last;
1350 
1351  if (cMemoryGetPointer(PrgId,Handle,(void**)&pFDescr) == OK)
1352  {
1353  if ((*pFDescr).hFile > MIN_HANDLE)
1354  {
1355  if (((*pFDescr).Access == OPEN_FOR_READ))
1356  {
1357  #ifdef DEBUG_C_MEMORY_FILE
1358  printf("Read from %-2d %5d %s [%d]\r\n",Handle,(*pFDescr).hFile,(*pFDescr).Filename,Size);
1359  #endif
1360  if (VMInstance.Handle >= 0)
1361  {
1362  if (Size > MIN_ARRAY_ELEMENTS)
1363  {
1364  pDestination = (DATA8*)VmMemoryResize(VMInstance.Handle,Size);
1365  }
1366  }
1367  No = 1;
1368  Last = 0;
1369  while ((No == 1) && (Size > 0))
1370  {
1371  No = (DATA8)read((*pFDescr).hFile,&Tmp,1);
1372 
1373  if (Del < DELS)
1374  {
1375  if (Del != DEL_NONE)
1376  {
1377  if (Del != DEL_CRLF)
1378  {
1379  if (Tmp == Delimiter[Del][0])
1380  {
1381  No = 0;
1382  }
1383  }
1384  else
1385  {
1386  if ((Tmp == Delimiter[Del][1]) && (Last == Delimiter[Del][0]))
1387  {
1388  No = 0;
1389  }
1390  Last = Tmp;
1391  }
1392  }
1393  }
1394 
1395  if (No)
1396  {
1397  *pDestination = Tmp;
1398  pDestination++;
1399  Size--;
1400  }
1401  }
1402  if (Size)
1403  {
1404  *pDestination = 0;
1405  }
1406 
1407  Result = NOBREAK;
1408  }
1409  }
1410  }
1411 
1412  if (Result == FAILBREAK)
1413  {
1415  }
1416 
1417  return (Result);
1418 }
1419 
1420 
1422 {
1423  DSPSTAT Result = FAILBREAK;
1424 
1425 #ifdef DEBUG_C_MEMORY_FILE
1426  FDESCR *pFDescr;
1427 
1428  if (MemoryInstance.pPoolList[PrgId][Handle].Type == POOL_TYPE_FILE)
1429  {
1430  if (cMemoryGetPointer(PrgId,Handle,(void**)&pFDescr) == OK)
1431  {
1432  printf("Close file %-2d %5d %s\r\n",Handle,(*pFDescr).hFile,(*pFDescr).Filename);
1433  }
1434  }
1435  else
1436  {
1437  printf("Close pool %-2d\r\n",Handle);
1438  }
1439 #endif
1440 
1441  Result = cMemoryFreeHandle(PrgId,Handle);
1442 
1443  if (Result == FAILBREAK)
1444  {
1446  }
1447 
1448  return (Result);
1449 }
1450 
1451 
1452 void cMemoryFindLogName(PRGID PrgId,char* pName)
1453 {
1454  HANDLER TmpHandle;
1455  FDESCR *pFDescr;
1456 
1457  pName[0] = 0;
1458 
1459  if ((PrgId >= 0) && (PrgId < MAX_PROGRAMS))
1460  {
1461  for (TmpHandle = 0;TmpHandle < MAX_HANDLES;TmpHandle++)
1462  {
1463  if (MemoryInstance.pPoolList[PrgId][TmpHandle].pPool != NULL)
1464  {
1465  if (MemoryInstance.pPoolList[PrgId][TmpHandle].Type == POOL_TYPE_FILE)
1466  {
1467  pFDescr = (FDESCR*)MemoryInstance.pPoolList[PrgId][TmpHandle].pPool;
1468  if ((*pFDescr).Access == OPEN_FOR_LOG)
1469  {
1470  snprintf(pName,MAX_FILENAME_SIZE,"%s",(*pFDescr).Filename);
1471  TmpHandle = MAX_HANDLES;
1472  }
1473  }
1474  }
1475  }
1476  }
1477 }
1478 
1479 
1480 RESULT cMemoryGetImage(DATA8 *pFileName,DATA16 Size,UBYTE *pBmp)
1481 {
1482  RESULT Result = FAIL;
1483  PRGID TmpPrgId;
1484  int File;
1485  char FilenameBuf[MAX_FILENAME_SIZE];
1486 
1487  TmpPrgId = CurrentProgramId();
1488 
1489  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,EXT_GRAPHICS) == OK)
1490  {
1491  File = open(FilenameBuf,O_RDONLY);
1492  if (File >= MIN_HANDLE)
1493  {
1494  read(File,pBmp,(size_t)Size);
1495  close(File);
1496  Result = OK;
1497  }
1498  }
1499 
1500  return (Result);
1501 }
1502 
1503 
1504 RESULT cMemoryGetMediaName(char *pChar,char *pName)
1505 {
1506  RESULT Result = FAIL;
1507  FILE *pFile;
1508  struct mntent *mountEntry;
1509 
1510  pFile = setmntent("/proc/mounts","r");
1511 
1512  while ((mountEntry = getmntent(pFile)) != NULL)
1513  {
1514  if(pChar[0] == 'm') // MMCCard detection
1515  {
1516 
1517  if(!strcmp(mountEntry->mnt_dir, "/media/card"))
1518  {
1519  pName = "card";
1520  Result = OK;
1521  }
1522 
1523  }
1524  if(pChar[0] == 's') // MassStorage detection
1525  {
1526  if(!strcmp(mountEntry->mnt_dir, "/media/usb"))
1527  {
1528  pName = "usb";
1529  Result = OK;
1530  }
1531  }
1532  }
1533 
1534  endmntent(pFile);
1535  return (Result);
1536 }
1537 
1538 
1539 typedef struct
1540 {
1545  DATA8 Folder[MAX_FILENAME_SIZE];
1546  DATA8 Entry[DIR_DEEPT][FILENAME_SIZE];
1547  DATA8 Priority[DIR_DEEPT];
1548 }
1549 FOLDER;
1550 
1551 
1552 enum
1553 {
1558 
1560 };
1561 
1563 {
1564  0, // -
1565  6, // Prjs
1566  5, // Apps
1567  8 // Tools
1568 };
1569 
1570 DATA8 FavouriteExts[FILETYPES] =
1571 {
1572  [TYPE_BYTECODE] = 1,
1573  [TYPE_SOUND] = 2,
1574  [TYPE_GRAPHICS] = 3,
1575  [TYPE_TEXT] = 4,
1576 };
1577 
1579 { // Priority
1580  // 0 1 2 3 4
1581  { },
1582  { "", "BrkProg_SAVE", "BrkDL_SAVE", "SD_Card", "USB_Stick", "TEST" },
1583  { "Port View", "Motor Control", "IR Control", "Brick Program", "Brick Datalog" },
1584  { "Volume", "Sleep", "Bluetooth", "WiFi", "Brick Info", "Test", "Performance", "Debug" }
1585 };
1586 
1587 
1588 void cMemorySortEntry(FOLDER *pMemory,UBYTE Type,char *pName)
1589 {
1590  DATA8 Sort;
1591  DATA8 Sort1;
1592  DATA8 Sort2;
1593  DATA8 Pointer;
1594  DATA8 Priority;
1595  DATA8 TmpPriority;
1596  DATA8 Favourites;
1597  char TmpEntry[FILENAME_SIZE];
1598 
1599  Sort = (*pMemory).Sort;
1600  Favourites = NoOfFavourites[Sort];
1601  Priority = Favourites;
1602 
1603  if ((Type != DT_DIR) && (Type != DT_LNK))
1604  { // Files
1605 
1606  // Get extension
1607  Pointer = 0;
1608  while ((pName[Pointer]) && (pName[Pointer] != '.'))
1609  {
1610  Pointer++;
1611  }
1612 
1613  // Priorities
1614  Priority = FavouriteExts[cMemoryFindType(&pName[Pointer])];
1615  if (Priority == 0)
1616  {
1617  Priority = FILETYPES;
1618  }
1619  Favourites = FILETYPES;
1620  }
1621  else
1622  { // Folders
1623 
1624  if (Sort == SORT_PRJS)
1625  {
1626  Priority = 0;
1627 
1628  for (Pointer = 1;Pointer < NoOfFavourites[Sort];Pointer++)
1629  {
1630  if (strcmp(pName,pFavourites[Sort][Pointer]) == 0)
1631  {
1632  Priority = Pointer;
1633  }
1634  }
1635  }
1636  else
1637  {
1638  for (Pointer = 0;Pointer < NoOfFavourites[Sort];Pointer++)
1639  {
1640  if (strcmp(pName,pFavourites[Sort][Pointer]) == 0)
1641  {
1642  Priority = Pointer;
1643  }
1644  }
1645  }
1646  }
1647  snprintf((char*)(*pMemory).Entry[(*pMemory).Entries],FILENAME_SIZE,"%s",pName);
1648  (*pMemory).Priority[(*pMemory).Entries] = Priority;
1649  ((*pMemory).Entries)++;
1650  if (Priority < Favourites)
1651  {
1652  for (Sort1 = 0;Sort1 < ((*pMemory).Entries - 1);Sort1++)
1653  {
1654  for (Sort2 = 0;Sort2 < ((*pMemory).Entries - 1);Sort2++)
1655  {
1656  if ((*pMemory).Priority[Sort2 + 1] < (*pMemory).Priority[Sort2])
1657  {
1658  TmpPriority = (*pMemory).Priority[Sort2];
1659  strcpy(TmpEntry,(char*)(*pMemory).Entry[Sort2]);
1660  (*pMemory).Priority[Sort2] = (*pMemory).Priority[Sort2 + 1];
1661  strcpy((char*)(*pMemory).Entry[Sort2],(char*)(*pMemory).Entry[Sort2 + 1]);
1662  (*pMemory).Priority[Sort2 + 1] = TmpPriority;
1663  strcpy((char*)(*pMemory).Entry[Sort2 + 1],(char*)TmpEntry);
1664  }
1665  }
1666  }
1667  }
1668 }
1669 
1670 
1671 void cMemorySortList(FOLDER *pMemory)
1672 {
1673  DATA16 Pointer;
1674 
1675  for (Pointer = 0;Pointer < (*pMemory).Entries;Pointer++)
1676  {
1677 #ifdef DEBUG
1678  printf("[%s](%d)(%d) %s\r\n",(char*)(*pMemory).Folder,(*pMemory).Sort,(*pMemory).Priority[Pointer],(char*)(*pMemory).Entry[Pointer]);
1679 #endif
1680  }
1681 }
1682 
1683 
1684 /*
1685  * Opens directory stream and allocate space for that and its items
1686  * Gives back the memory handle
1687  *
1688  */
1689 
1690 RESULT cMemoryOpenFolder(PRGID PrgId,DATA8 Type,DATA8 *pFolderName,HANDLER *pHandle)
1691 {
1692  RESULT Result;
1693  FOLDER *pMemory;
1694 
1695  Result = cMemoryAlloc(PrgId,POOL_TYPE_MEMORY,(GBINDEX)sizeof(FOLDER),((void**)&pMemory),pHandle);
1696  if (Result == OK)
1697  {
1698  (*pMemory).pDir = NULL;
1699  (*pMemory).Entries = 0;
1700  (*pMemory).Type = Type;
1701  snprintf((char*)(*pMemory).Folder,MAX_FILENAME_SIZE,"%s",(char*)pFolderName);
1702  (*pMemory).pDir = opendir((char*)(*pMemory).Folder);
1703  if ((*pMemory).pDir == NULL)
1704  {
1705  Result = FAIL;
1706  }
1707  else
1708  {
1709  if (strcmp((char*)pFolderName,vmPRJS_DIR) == 0)
1710  {
1711  (*pMemory).Sort = SORT_PRJS;
1712  }
1713  else
1714  {
1715  if (strcmp((char*)pFolderName,vmAPPS_DIR) == 0)
1716  {
1717  (*pMemory).Sort = SORT_APPS;
1718  }
1719  else
1720  {
1721  if (strcmp((char*)pFolderName,vmTOOLS_DIR) == 0)
1722  {
1723  (*pMemory).Sort = SORT_TOOLS;
1724  }
1725  else
1726  {
1727  (*pMemory).Sort = SORT_NONE;
1728  }
1729  }
1730  }
1731  }
1732  }
1733 
1734  return (Result);
1735 }
1736 
1737 
1738 /*
1739  * Count and sort items - one for each call
1740  * Return total count
1741  */
1742 RESULT cMemoryGetFolderItems(PRGID PrgId,HANDLER Handle,DATA16 *pItems)
1743 {
1744  RESULT Result;
1745  FOLDER *pMemory;
1746  char Ext[vmEXTSIZE];
1747  struct dirent *pEntry;
1748 
1749  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
1750 
1751  if (Result == OK)
1752  { // Handle ok
1753 
1754  if ((*pMemory).pDir != NULL)
1755  {
1756  pEntry = readdir((*pMemory).pDir);
1757  if (pEntry != NULL)
1758  { // More entries
1759 
1760  if ((*pMemory).Entries < DIR_DEEPT)
1761  {
1762  if ((*pEntry).d_name[0] != '.')
1763  {
1764  if (strcmp((*pEntry).d_name,"CVS") != 0)
1765  {
1766  if ((*pMemory).Type == TYPE_FOLDER)
1767  {
1768  if (((*pEntry).d_type == DT_DIR) || ((*pEntry).d_type == DT_LNK))
1769  { // Folders
1770 
1771  cMemorySortEntry(pMemory,(*pEntry).d_type,(*pEntry).d_name);
1772 #ifdef DEBUG
1773  printf("[%s](%d) %s\r\n",(char*)(*pMemory).Folder,(*pMemory).Sort,(*pEntry).d_name);
1774 #endif
1775  }
1776  }
1777  else
1778  {
1779  if ((*pEntry).d_type == DT_REG)
1780  { // Files
1781 
1782  FindName((*pEntry).d_name,NULL,NULL,Ext);
1783  if (cMemoryFindType(Ext))
1784  {
1785  cMemorySortEntry(pMemory,(*pEntry).d_type,(*pEntry).d_name);
1786 #ifdef DEBUG
1787  printf("[%s](%d) %s\r\n",(char*)(*pMemory).Folder,(*pMemory).Sort,(*pEntry).d_name);
1788 #endif
1789  }
1790  }
1791  }
1792  }
1793  }
1794  }
1795  Result = BUSY;
1796  }
1797  else
1798  { // No more entries
1799 
1800  cMemorySortList(pMemory);
1801  closedir((*pMemory).pDir);
1802  (*pMemory).pDir = NULL;
1803  }
1804  }
1805  }
1806  *pItems = ((*pMemory).Entries);
1807 
1808  return (Result);
1809 }
1810 
1811 
1812 /*
1813  * Get display-able name - only name not path and extension
1814  */
1815 RESULT cMemoryGetItemName(PRGID PrgId,HANDLER Handle,DATA16 Item,DATA8 Length,DATA8 *pName,DATA8 *pType,DATA8 *pPriority)
1816 {
1817  RESULT Result = FAIL;
1818  FOLDER *pMemory;
1819  char Name[vmNAMESIZE];
1820  char Ext[vmEXTSIZE];
1821 
1822  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
1823  *pType = 0;
1824  *pPriority = 127;
1825 
1826  if (Result == OK)
1827  { // Handle ok
1828 
1829  if ((Item > 0) && (Item <= (*pMemory).Entries))
1830  { // Item ok
1831 
1832  if (Length >= 2)
1833  {
1834  if (cMemoryCheckFilename((char*)(*pMemory).Entry[Item - 1],NULL,Name,Ext) == OK)
1835  {
1836  *pType = cMemoryFindType(Ext);
1837  if (strlen(Name) >= Length)
1838  {
1839  Name[Length - 1] = 0;
1840  Name[Length - 2] = 0x7F;
1841  }
1842 
1843  snprintf((char*)pName,(int)Length,"%s",Name);
1844  *pPriority = (*pMemory).Priority[Item - 1];
1845  }
1846  else
1847  {
1848  Result = FAIL;
1849  }
1850  }
1851  else
1852  {
1853  Result = FAIL;
1854  }
1855  }
1856  else
1857  {
1858  Result = FAIL;
1859  }
1860 
1861  }
1862  return (Result);
1863 }
1864 
1865 
1866 /*
1867  * Get icon image
1868  */
1869 RESULT cMemoryGetItemIcon(PRGID PrgId,HANDLER Handle,DATA16 Item,HANDLER *pHandle,DATA32 *pImagePointer)
1870 {
1871  RESULT Result = FAIL;
1872  FOLDER *pMemory;
1873  char Filename[MAX_FILENAME_SIZE];
1874  DATA32 ISize;
1875  IP pImage;
1876  struct stat FileStatus;
1877  int hFile;
1878 
1879  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
1880 
1881  if (Result == OK)
1882  { // Handle ok
1883 
1884  Result = FAIL;
1885  if ((Item > 0) && (Item <= (*pMemory).Entries))
1886  { // Item ok
1887 
1888  snprintf(Filename,MAX_FILENAME_SIZE,"%s/%s/%s%s",(char*)(*pMemory).Folder,(char*)(*pMemory).Entry[Item - 1],ICON_FILE_NAME,EXT_GRAPHICS);
1889 
1890  hFile = open(Filename,O_RDONLY);
1891 
1892  if (hFile >= MIN_HANDLE)
1893  {
1894 
1895  stat(Filename,&FileStatus);
1896  ISize = FileStatus.st_size;
1897 
1898  // allocate memory to contain the whole file:
1899  if (cMemoryAlloc(PrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pImage,pHandle) == OK)
1900  {
1901 
1902  if ((DATA32)read(hFile,pImage,ISize) == ISize)
1903  {
1904  *pImagePointer = (DATA32)pImage;
1905  Result = OK;
1906  }
1907  }
1908 
1909  close(hFile);
1910  }
1911  }
1912  }
1913 
1914  return (Result);
1915 }
1916 
1917 
1918 /*
1919  * Get text
1920  */
1921 RESULT cMemoryGetItemText(PRGID PrgId,HANDLER Handle,DATA16 Item,DATA8 Length,DATA8 *pText)
1922 {
1923  RESULT Result = FAIL;
1924  FOLDER *pMemory;
1925  char Filename[MAX_FILENAME_SIZE];
1926  int hFile;
1927  DATA8 Tmp;
1928  char Termination[2] = "\t";
1929  ssize_t No;
1930 
1931  for (Tmp = 0;Tmp < Length;Tmp++)
1932  {
1933  pText[Tmp] = 0;
1934  }
1935  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
1936 
1937  if (Result == OK)
1938  { // Handle ok
1939 
1940  if ((Item > 0) && (Item <= (*pMemory).Entries) && Length)
1941  { // Item ok
1942 
1943 // snprintf(Filename,MAX_FILENAME_SIZE,"%s/%s/%s%s",(char*)(*pMemory).Folder,(char*)(*pMemory).Entry[Item - 1],TEXT_FILE_NAME,EXT_TEXT);
1944  snprintf(Filename,MAX_FILENAME_SIZE,"%s/%s%s",vmSETTINGS_DIR,(char*)(*pMemory).Entry[Item - 1],EXT_TEXT);
1945  hFile = open(Filename,O_RDONLY);
1946  if (hFile >= MIN_HANDLE)
1947  {
1948  Result = OK;
1949  No = 1;
1950  while ((No == 1) && (Length > 1))
1951  {
1952  No = read(hFile,&Tmp,1);
1953  if ((Tmp == Termination[0]) || (Tmp == '\r') || (Tmp == '\n'))
1954  {
1955  No = 0;
1956  }
1957  if (No)
1958  {
1959  *pText = Tmp;
1960  pText++;
1961  *pText = 0;
1962  Length--;
1963  }
1964  }
1965  close(hFile);
1966  }
1967  }
1968  else
1969  {
1970  Result = FAIL;
1971  }
1972 
1973  }
1974 
1975  return (Result);
1976 }
1977 
1978 
1979 /*
1980  * Get text
1981  */
1982 RESULT cMemorySetItemText(PRGID PrgId,HANDLER Handle,DATA16 Item,DATA8 *pText)
1983 {
1984  RESULT Result = FAIL;
1985  FOLDER *pMemory;
1986  char Filename[MAX_FILENAME_SIZE];
1987  LFILE *pFile;
1988  DATA8 Length;
1989 
1990  Length = (DATA8)strlen((char*)pText);
1991  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
1992 
1993  if (Result == OK)
1994  { // Handle ok
1995 
1996  if ((Item > 0) && (Item <= (*pMemory).Entries) && Length)
1997  { // Item ok
1998 
1999  snprintf(Filename,MAX_FILENAME_SIZE,"%s/%s/%s%s",(char*)(*pMemory).Folder,(char*)(*pMemory).Entry[Item - 1],TEXT_FILE_NAME,EXT_TEXT);
2000 
2001  pFile = fopen (Filename, "wb");
2002  if (NULL != pFile)
2003  {
2004  fwrite(pText,1,Length,pFile);
2005  Result = OK;
2006  fclose (pFile);
2007  }
2008  }
2009  else
2010  {
2011  Result = FAIL;
2012  }
2013 
2014  }
2015 
2016  return (Result);
2017 }
2018 
2019 
2020 /*
2021  * Get full name including path and extension
2022  */
2023 RESULT cMemoryGetItem(PRGID PrgId,HANDLER Handle,DATA16 Item,DATA8 Length,DATA8 *pName,DATA8 *pType)
2024 {
2025  RESULT Result = FAIL;
2026  FOLDER *pMemory;
2027  char Folder[vmPATHSIZE];
2028  char Name[vmNAMESIZE];
2029  char Ext[vmEXTSIZE];
2030 
2031  Result = cMemoryGetPointer(PrgId,Handle,((void**)&pMemory));
2032  *pType = 0;
2033 
2034  if (Result == OK)
2035  { // Handle ok
2036 
2037  if ((Item > 0) && (Item <= (*pMemory).Entries))
2038  { // Item ok
2039 
2040  if (cMemoryCheckFilename((char*)(*pMemory).Entry[Item - 1],Folder,Name,Ext) == OK)
2041  {
2042  *pType = cMemoryFindType(Ext);
2043  snprintf((char*)pName,(int)Length,"%s%s/%s",(char*)(*pMemory).Folder,Folder,Name);
2044  }
2045  else
2046  {
2047  Result = FAIL;
2048  }
2049  }
2050  else
2051  {
2052  Result = FAIL;
2053  }
2054 
2055  }
2056 
2057  return (Result);
2058 }
2059 
2060 
2061 /*
2062  * Close directory stream and free memory handle
2063  */
2064 void cMemoryCloseFolder(PRGID PrgId,HANDLER *pHandle)
2065 {
2066  RESULT Result;
2067  FOLDER *pMemory;
2068 
2069  Result = cMemoryGetPointer(PrgId,*pHandle,((void**)&pMemory));
2070 
2071  if (Result == OK)
2072  { // Handle ok
2073 
2074  if ((*pMemory).pDir != NULL)
2075  {
2076  closedir((*pMemory).pDir);
2077  }
2078  cMemoryFreePool(PrgId,(void*)pMemory);
2079  }
2080  *pHandle = 0;
2081 }
2082 
2083 
2084 //******* BYTE CODE SNIPPETS **************************************************
2085 
2086 
2303 void cMemoryFile(void)
2304 {
2305 
2306  IP TmpIp;
2307  DSPSTAT DspStat = BUSYBREAK;
2308  DATA8 Cmd;
2309  DATA32 ImagePointer;
2310  DATA32 ISize;
2311  IP pImage;
2312  HANDLER TmpHandle;
2313  PRGID TmpPrgId;
2314  DATA32 Data32;
2315 
2316  DATA8 *pFileName;
2317  char FilenameBuf[vmFILENAMESIZE];
2318  char PathBuf[vmPATHSIZE];
2319  char NameBuf[vmNAMESIZE];
2320  char ExtBuf[vmEXTSIZE];
2321 
2322  char SourceBuf[vmFILENAMESIZE];
2323  char DestinationBuf[vmFILENAMESIZE];
2324 
2325  DATA8 *pSource;
2326  DATA8 *pDestination;
2327 
2328  char PrgNamePath[SUBFOLDERNAME_SIZE];
2329  char PrgNameBuf[MAX_FILENAME_SIZE];
2330  char DestinationName[MAX_FILENAME_SIZE];
2331  DATA16 PrgNo;
2332  DATA8 Item;
2333  DATA8 Items;
2334  DATA8 Lng;
2335  DATA8 Tmp;
2336  DATA8 Del;
2337  DATA8 *pFolderName;
2338  int hFile;
2339  char Buffer[LOGBUFFER_SIZE];
2340  DATAF DataF;
2341  DATA16 Bytes;
2342  DATA8 Figures;
2343  DATA8 Decimals;
2344  struct stat FileStatus;
2345  DATAF *pValue;
2346  DATA32 Time;
2347  DESCR *pDescr;
2348  DATA32 UsedElements;
2349  DATA32 Elements;
2350  DATA32 ElementSize;
2351 
2352  DATA32 STime;
2353  DATA32 STick;
2354  DATA32 NTick;
2355  DATA32 SIIM;
2356  DATA32 DIM;
2357  DATA8 *pSData;
2358  DATA8 Error = 0;
2359  DATA32 TotalRam;
2360  DATA32 FreeRam;
2361 
2362  void *pTmp;
2363  HANDLER TmpHandle2;
2364 
2365  TmpPrgId = CurrentProgramId();
2366  TmpIp = GetObjectIp();
2367  Cmd = *(DATA8*)PrimParPointer();
2368  ImagePointer = (DATA32)NULL;
2369  ISize = (DATA32)0;
2370 
2371  switch (Cmd)
2372  { // Function
2373 
2374  case OPEN_APPEND :
2375  {
2376  pFileName = (DATA8*)PrimParPointer();
2377 
2378  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,"") == OK)
2379  {
2380 
2381 #ifdef DEBUG_TRACE_FILENAME
2382  printf("c_memory cMemoryFile: OPEN_APPEND [%s]\r\n",FilenameBuf);
2383 #endif
2384  DspStat = cMemoryOpenFile(TmpPrgId,OPEN_FOR_APPEND,(char*)FilenameBuf,&TmpHandle,&ISize);
2385  }
2386 
2387  *(DATA16*)PrimParPointer() = TmpHandle;
2388  }
2389  break;
2390 
2391  case OPEN_READ :
2392  {
2393  pFileName = (DATA8*)PrimParPointer();
2394 
2395  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,"") == OK)
2396  {
2397 
2398 #ifdef DEBUG_TRACE_FILENAME
2399  printf("c_memory cMemoryFile: OPEN_READ [%s]\r\n",FilenameBuf);
2400 #endif
2401  DspStat = cMemoryOpenFile(TmpPrgId,OPEN_FOR_READ,FilenameBuf,&TmpHandle,&ISize);
2402  }
2403 
2404  *(DATA16*)PrimParPointer() = TmpHandle;
2405  *(DATA32*)PrimParPointer() = ISize;
2406  }
2407  break;
2408 
2409  case OPEN_WRITE :
2410  {
2411  pFileName = (DATA8*)PrimParPointer();
2412 
2413  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,"") == OK)
2414  {
2415 
2416 #ifdef DEBUG_TRACE_FILENAME
2417  printf("c_memory cMemoryFile: OPEN_WRITE [%s]\r\n",FilenameBuf);
2418 #endif
2419  DspStat = cMemoryOpenFile(TmpPrgId,OPEN_FOR_WRITE,FilenameBuf,&TmpHandle,&ISize);
2420 
2421  }
2422 
2423  *(DATA16*)PrimParPointer() = TmpHandle;
2424  }
2425  break;
2426 
2427  case CLOSE :
2428  {
2429  TmpHandle = *(DATA16*)PrimParPointer();
2430 
2431  DspStat = cMemoryCloseFile(TmpPrgId,TmpHandle);
2432  }
2433  break;
2434 
2435  case WRITE_TEXT :
2436  {
2437  TmpHandle = *(DATA16*)PrimParPointer();
2438  Del = *(DATA8*)PrimParPointer();
2439  pSource = (DATA8*)PrimParPointer();
2440 
2441  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)strlen((char*)pSource),Del,pSource);
2442  }
2443  break;
2444 
2445  case READ_TEXT :
2446  {
2447  TmpHandle = *(DATA16*)PrimParPointer();
2448  Del = *(DATA8*)PrimParPointer();
2449  Lng = (DATA8)(*(DATA16*)PrimParPointer());
2450  pDestination = (DATA8*)PrimParPointer();
2451 
2452  DspStat = cMemoryReadFile(TmpPrgId,TmpHandle,(DATA32)Lng,Del,pDestination);
2453  }
2454  break;
2455 
2456  case WRITE_VALUE :
2457  {
2458  TmpHandle = *(DATA16*)PrimParPointer();
2459  Del = *(DATA8*)PrimParPointer();
2460  DataF = *(DATAF*)PrimParPointer();
2461  Figures = *(DATA8*)PrimParPointer();
2462  Decimals = *(DATA8*)PrimParPointer();
2463 
2464  snprintf(Buffer,LOGBUFFER_SIZE,"%*.*f",Figures,Decimals,DataF);
2465  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)strlen((char*)Buffer),Del,(DATA8*)Buffer);
2466  }
2467  break;
2468 
2469  case READ_VALUE :
2470  {
2471  TmpHandle = *(DATA16*)PrimParPointer();
2472  Del = *(DATA8*)PrimParPointer();
2473 
2474  Lng = 64;
2475  Buffer[0] = 0;
2476  pDestination = (DATA8*)Buffer;
2477  DataF = (DATAF)0;
2478  DspStat = cMemoryReadFile(TmpPrgId,TmpHandle,(DATA32)Lng,Del,pDestination);
2479  sscanf(Buffer,"%f",&DataF);
2480 
2481  *(DATAF*)PrimParPointer() = DataF;
2482  }
2483  break;
2484 
2485  case WRITE_BYTES :
2486  {
2487  TmpHandle = *(DATA16*)PrimParPointer();
2488  Bytes = *(DATA16*)PrimParPointer();
2489  pSource = (DATA8*)PrimParPointer();
2490 
2491  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)Bytes,DEL_NONE,pSource);
2492  }
2493  break;
2494 
2495  case READ_BYTES :
2496  {
2497  TmpHandle = *(DATA16*)PrimParPointer();
2498  Bytes = *(DATA16*)PrimParPointer();
2499  pDestination = (DATA8*)PrimParPointer();
2500 
2501  DspStat = cMemoryReadFile(TmpPrgId,TmpHandle,(DATA32)Bytes,DEL_NONE,pDestination);
2502  }
2503  break;
2504 
2505  case OPEN_LOG :
2506  {
2507  pFileName = (DATA8*)PrimParPointer();
2508 
2509  STime = *(DATA32*)PrimParPointer();
2510  STick = *(DATA32*)PrimParPointer();
2511  NTick = *(DATA32*)PrimParPointer();
2512  SIIM = *(DATA32*)PrimParPointer();
2513  DIM = *(DATA32*)PrimParPointer();
2514 
2515  pSData = (DATA8*)PrimParPointer();
2516 
2517  TmpHandle = 0;
2518 
2519  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,vmEXT_DATALOG) == OK)
2520  {
2521 
2522 #ifdef DEBUG_TRACE_FILENAME
2523  printf("c_memory cMemoryFile: OPEN_LOG [%s]\r\n",FilenameBuf);
2524 #endif
2525  Bytes = snprintf(Buffer,LOGBUFFER_SIZE,"Sync data\t%d\t%d\t%d\t%d\t%d\r\n%s",STime,STick,NTick,SIIM,DIM,pSData);
2526 
2527  DspStat = NOBREAK;
2528 
2529  if ((SIIM < MIN_LIVE_UPDATE_TIME) || (FilenameBuf[0] == 0))
2530  { // Log in ram
2531 
2532  if (FilenameBuf[0])
2533  {
2534  DspStat = cMemoryOpenFile(TmpPrgId,OPEN_FOR_LOG,FilenameBuf,&TmpHandle,&ISize);
2535  }
2536  if (DspStat == NOBREAK)
2537  {
2538  Elements = LOGBUFFER_SIZE;
2539 
2540  ElementSize = sizeof(DATA8);
2541  ISize = Elements * ElementSize + sizeof(DESCR);
2542 
2543  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pTmp,&TmpHandle) == OK)
2544  {
2545  (*(DESCR*)pTmp).Type = DATA_8;
2546  (*(DESCR*)pTmp).ElementSize = (DATA8)ElementSize;
2547  (*(DESCR*)pTmp).Elements = Elements;
2548  (*(DESCR*)pTmp).UsedElements = 0;
2549 
2550  #ifdef DEBUG_C_MEMORY_LOG
2551  if (pFileName[0])
2552  {
2553  printf("LOG_OPEN %d into ram file %s\r\n",TmpHandle,FilenameBuf);
2554  printf(" header %d into ram file %d bytes\r\n",TmpHandle,Bytes);
2555  }
2556  else
2557  {
2558  printf("LOG_OPEN %d into ram\r\n",TmpHandle);
2559  printf(" header %d into ram %d bytes\r\n",TmpHandle,Bytes);
2560  }
2561  #endif
2562  pDescr = (DESCR*)pTmp;
2563 
2564  pDestination = (DATA8*)(*pDescr).pArray;
2565  UsedElements = (*pDescr).UsedElements;
2566 
2567  Elements = 0;
2568  while (Bytes)
2569  {
2570  pDestination[UsedElements] = Buffer[Elements];
2571  UsedElements++;
2572  Elements++;
2573  Bytes--;
2574  }
2575  (*pDescr).UsedElements = UsedElements;
2576  }
2577  else
2578  {
2579  DspStat = FAILBREAK;
2580  }
2581  }
2582  }
2583  else
2584  { // Log in file
2585 
2586  DspStat = cMemoryOpenFile(TmpPrgId,OPEN_FOR_LOG,FilenameBuf,&TmpHandle,&ISize);
2587  if (DspStat == NOBREAK)
2588  {
2589  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)Bytes,DEL_NONE,(DATA8*)Buffer);
2590  #ifdef DEBUG_C_MEMORY_LOG
2591  printf("LOG_OPEN %d into file %s\r\n",TmpHandle,(char*)pFileName);
2592  printf(" header %d file %d bytes\r\n",TmpHandle,Bytes);
2593  #endif
2594  }
2595  }
2596  }
2597  *(HANDLER*)PrimParPointer() = (HANDLER)TmpHandle;
2598  }
2599  break;
2600 
2601  case WRITE_LOG :
2602  {
2603  TmpHandle = *(DATA16*)PrimParPointer();
2604  Time = *(DATA32*)PrimParPointer();
2605  Items = *(DATA8*)PrimParPointer();
2606  pValue = (DATAF*)PrimParPointer();
2607 
2608  DspStat = FAILBREAK;
2609 
2610  if (Items)
2611  {
2612 #ifndef LOG_ASCII
2613 
2614  DataF = (DATAF)Time;
2615  Bytes = 0;
2616 
2617  memcpy((void*)&Buffer[Bytes],(void*)&DataF,sizeof(DATAF));
2618  Bytes += sizeof(DATAF);
2619 
2620  for (Item = 0;Item < Items;Item++)
2621  {
2622  memcpy((void*)&Buffer[Bytes],(void*)&pValue[Item],sizeof(DATAF));
2623  Bytes += sizeof(DATAF);
2624  }
2625 
2626 #else
2627  Bytes = (DATA16)snprintf(Buffer,LOGBUFFER_SIZE,"%08d\t",Time);
2628  for (Item = 0;Item < Items;Item++)
2629  {
2630 
2631  if (Item != (Items - 1))
2632  {
2633  Bytes += snprintf(&Buffer[Bytes],LOGBUFFER_SIZE - Bytes,"%.1f\t",pValue[Item]);
2634  }
2635  else
2636  {
2637  Bytes += snprintf(&Buffer[Bytes],LOGBUFFER_SIZE - Bytes,"%.1f\r\n",pValue[Item]);
2638  }
2639  }
2640 #endif
2641 
2642  if (MemoryInstance.pPoolList[TmpPrgId][TmpHandle].Type == POOL_TYPE_MEMORY)
2643  { // Log to memory
2644 
2645  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
2646  {
2647  pDescr = (DESCR*)pTmp;
2648 
2649  UsedElements = (DATA32)Bytes + (*pDescr).UsedElements;
2650  Elements = (*pDescr).Elements;
2651 
2652  if (UsedElements > Elements)
2653  {
2654  Elements += LOGBUFFER_SIZE;
2655 #ifdef DEBUG_C_MEMORY_LOG
2656  printf("LOG_WRITE %d resizing ram to %d\r\n",TmpHandle,Elements);
2657 #endif
2658  cMemoryGetUsage(&TotalRam,&FreeRam,0);
2659 #ifdef DEBUG_C_MEMORY_LOG
2660  printf("Free memory %u KB\r\n",FreeRam);
2661 #endif
2662  if (FreeRam > RESERVED_MEMORY)
2663  {
2664  if (cMemoryResize(TmpPrgId,TmpHandle,Elements) == NULL)
2665  {
2666  Error = OUT_OF_MEMORY;
2667  }
2668  }
2669  else
2670  {
2671  Error = OUT_OF_MEMORY;
2672  }
2673 
2674  }
2675  if (!Error)
2676  {
2677  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
2678  {
2679  pDescr = (DESCR*)pTmp;
2680 
2681  pDestination = (DATA8*)(*pDescr).pArray;
2682  UsedElements = (*pDescr).UsedElements;
2683 
2684  #ifdef DEBUG_C_MEMORY_LOG
2685  printf("LOG_WRITE %d ram %d bytes\r\n",TmpHandle,Bytes);
2686  #endif
2687  memcpy((void*)&pDestination[UsedElements],Buffer,(size_t)Bytes);
2688  (*pDescr).UsedElements = UsedElements + (DATA32)Bytes;
2689 
2690  DspStat = NOBREAK;
2691 
2692  }
2693  else
2694  {
2695  Error = OUT_OF_MEMORY;
2696  }
2697  }
2698  }
2699 
2700  }
2701  else
2702  { // Log to file
2703 
2704 #ifdef DEBUG_C_MEMORY_LOG
2705  printf("LOG_WRITE %d file %d bytes\r\n",TmpHandle,Bytes);
2706 #endif
2707  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)Bytes,DEL_NONE,(DATA8*)Buffer);
2708  }
2709  }
2710  DspStat = NOBREAK;
2711  }
2712  break;
2713 
2714  case CLOSE_LOG :
2715  {
2716  TmpHandle = *(DATA16*)PrimParPointer();
2717  pFileName = (DATA8*)PrimParPointer();
2718 
2719  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,vmEXT_DATALOG) == OK)
2720  {
2721  DspStat = cMemoryGetFileHandle(TmpPrgId,FilenameBuf,&TmpHandle2,&Tmp);
2722 #ifdef DEBUG_TRACE_FILENAME
2723  printf("c_memory cMemoryFile: CLOSE_LOG [%s]\r\n",FilenameBuf);
2724 #endif
2725 
2726  if (MemoryInstance.pPoolList[TmpPrgId][TmpHandle].Type == POOL_TYPE_MEMORY)
2727  { // Log to memory
2728 
2729  if (FilenameBuf[0])
2730  {
2731  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
2732  {
2733  pDescr = (DESCR*)pTmp;
2734 
2735  if (DspStat == NOBREAK)
2736  {
2737  pSource = (DATA8*)(*pDescr).pArray;
2738  UsedElements = (*pDescr).UsedElements;
2739 
2740 #ifndef LOG_ASCII
2741  Buffer[0] = 0xFF;
2742  Buffer[1] = 0xFF;
2743  Buffer[2] = 0xFF;
2744  Buffer[3] = 0xFF;
2745  Buffer[4] = 0xFF;
2746  Buffer[5] = 0xFF;
2747  Buffer[6] = 0xFF;
2748  Buffer[7] = 0xFF;
2749 
2750  Bytes = 8;
2751 #else
2752  Buffer[0] = 'F';
2753  Buffer[1] = 'F';
2754  Buffer[2] = 'F';
2755  Buffer[3] = 'F';
2756  Buffer[4] = 'F';
2757  Buffer[5] = 'F';
2758  Buffer[6] = 'F';
2759  Buffer[7] = 'F';
2760  Buffer[8] = '\r';
2761  Buffer[9] = '\n';
2762 
2763  Bytes = 10;
2764 #endif
2765 
2766 
2767  #ifdef DEBUG_C_MEMORY_LOG
2768  printf("LOG_WRITE %d ram %d log end signature\r\n",TmpHandle,Bytes);
2769  #endif
2770  memcpy((void*)&pSource[UsedElements],Buffer,(size_t)Bytes);
2771  UsedElements += (DATA32)Bytes;
2772 
2773  cMemoryGetUsage(&TotalRam,&FreeRam,0);
2774  if (UsedElements > ((FreeRam - RESERVED_MEMORY) * KB))
2775  {
2776  UsedElements = (FreeRam - RESERVED_MEMORY) * KB;
2777  }
2778 
2779  #ifdef DEBUG_C_MEMORY_LOG
2780  printf("LOG_CLOSE %d ram and save %d bytes to %s\r\n",TmpHandle,UsedElements,(char*)pFileName);
2781  #endif
2782  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle2,(DATA32)UsedElements,DEL_NONE,pSource);
2783  }
2784  if (DspStat == NOBREAK)
2785  {
2786  DspStat = cMemoryCloseFile(TmpPrgId,TmpHandle2);
2787  sync();
2788  }
2789  }
2790  }
2791  else
2792  {
2793  cMemoryFreeHandle(TmpPrgId,TmpHandle);
2794 
2795  DspStat = NOBREAK;
2796  }
2797  }
2798  else
2799  {
2800 #ifndef LOG_ASCII
2801  Buffer[0] = 0xFF;
2802  Buffer[1] = 0xFF;
2803  Buffer[2] = 0xFF;
2804  Buffer[3] = 0xFF;
2805  Buffer[4] = 0xFF;
2806  Buffer[5] = 0xFF;
2807  Buffer[6] = 0xFF;
2808  Buffer[7] = 0xFF;
2809 
2810  Bytes = 8;
2811 #else
2812  Buffer[0] = 'F';
2813  Buffer[1] = 'F';
2814  Buffer[2] = 'F';
2815  Buffer[3] = 'F';
2816  Buffer[4] = 'F';
2817  Buffer[5] = 'F';
2818  Buffer[6] = 'F';
2819  Buffer[7] = 'F';
2820  Buffer[8] = '\r';
2821  Buffer[9] = '\n';
2822 
2823  Bytes = 10;
2824 #endif
2825 
2826  #ifdef DEBUG_C_MEMORY_LOG
2827  printf("LOG_WRITE %d file %d 0xFF\r\n",TmpHandle,Bytes);
2828  #endif
2829  DspStat = cMemoryWriteFile(TmpPrgId,TmpHandle,(DATA32)Bytes,DEL_NONE,(DATA8*)Buffer);
2830 
2831  DspStat = cMemoryCloseFile(TmpPrgId,TmpHandle);
2832 
2833  #ifdef DEBUG_C_MEMORY_LOG
2834  printf("LOG_CLOSE %d file\r\n",TmpHandle);
2835  #endif
2836  sync();
2837  }
2838  }
2839  DspStat = NOBREAK;
2840  }
2841  break;
2842 
2843  case GET_LOG_NAME :
2844  {
2845  Lng = *(DATA8*)PrimParPointer();
2846  pFileName = (DATA8*)PrimParPointer();
2847 
2848  cMemoryFindLogName(TmpPrgId,DestinationName);
2849 
2850  if (VMInstance.Handle >= 0)
2851  {
2852  Data32 = (DATA32)strlen(DestinationName);
2853  Data32 += 1;
2854  if (Data32 > MIN_ARRAY_ELEMENTS)
2855  {
2856  pFileName = (DATA8*)VmMemoryResize(VMInstance.Handle,Data32);
2857  }
2858  Lng = (DATA8)Data32;
2859  }
2860  if (pFileName != NULL)
2861  {
2862  snprintf((char*)pFileName,(int)Lng,"%s",DestinationName);
2863  }
2864  DspStat = NOBREAK;
2865  }
2866  break;
2867 
2868  case GET_HANDLE :
2869  {
2870  pFileName = (DATA8*)PrimParPointer();
2871 
2872  TmpHandle = 0;
2873  Tmp = 0;
2874 
2875  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,"") == OK)
2876  {
2877  DspStat = cMemoryGetFileHandle(TmpPrgId,FilenameBuf,&TmpHandle,&Tmp);
2878 #ifdef DEBUG_TRACE_FILENAME
2879  printf("c_memory cMemoryFile: GET_HANDLE [%s]\r\n",FilenameBuf);
2880 #endif
2881  }
2882 
2883  *(DATA16*)PrimParPointer() = TmpHandle;
2884  *(DATA8*)PrimParPointer() = Tmp;
2885  }
2886  break;
2887 
2888  case REMOVE :
2889  {
2890  pFileName = (DATA8*)PrimParPointer();
2891 
2892  if (ConstructFilename(TmpPrgId,(char*)pFileName,FilenameBuf,"") == OK)
2893  {
2894  cMemoryDeleteSubFolders(FilenameBuf);
2895 #ifdef DEBUG_TRACE_FILENAME
2896  printf("c_memory cMemoryFile: REMOVE [%s]\r\n",FilenameBuf);
2897 #endif
2898  SetUiUpdate();
2899  }
2900  DspStat = NOBREAK;
2901  }
2902  break;
2903 
2904  case MAKE_FOLDER :
2905  {
2906  pDestination = (DATA8*)PrimParPointer();
2907 
2908  snprintf(PathBuf,vmPATHSIZE,"%s",pDestination);
2909 
2910  Data32 = (DATA32)strlen(PathBuf);
2911  if (Data32)
2912  {
2913  if (PathBuf[Data32 - 1] == '/')
2914  {
2915  PathBuf[Data32 - 1] = 0;
2916  }
2917  }
2918 
2919  Tmp = 0;
2920  if (stat((char*)PathBuf,&FileStatus) == 0)
2921  {
2922  Tmp = 1;
2923 #ifdef DEBUG_TRACE_FILENAME
2924  printf("c_memory cMemoryFile: MAKE_FOLDER [%s] already present\r\n",PathBuf);
2925 #endif
2926  }
2927  else
2928  {
2929  mkdir((char*)PathBuf,DIRPERMISSIONS);
2930  chmod((char*)PathBuf,DIRPERMISSIONS);
2931  sync();
2932 
2933 #ifdef DEBUG_TRACE_FILENAME
2934  printf("c_memory cMemoryFile: MAKE_FOLDER [%s]\r\n",PathBuf);
2935 #endif
2936 
2937  if (stat((char*)PathBuf,&FileStatus) == 0)
2938  {
2939  Tmp = 1;
2940  }
2941  }
2942  *(DATA8*)PrimParPointer() = Tmp;
2943 
2944  DspStat = NOBREAK;
2945  }
2946  break;
2947 
2948  case MOVE :
2949  {
2950  pSource = (DATA8*)PrimParPointer();
2951  pDestination = (DATA8*)PrimParPointer();
2952 
2953  if (ConstructFilename(TmpPrgId,(char*)pSource,SourceBuf,"") == OK)
2954  {
2955  if (ConstructFilename(TmpPrgId,(char*)pDestination,DestinationBuf,"") == OK)
2956  {
2957 
2958  snprintf(Buffer,LOGBUFFER_SIZE,"cp -r \"%s\" \"%s\"",SourceBuf,DestinationBuf);
2959 #ifdef DEBUG_TRACE_FILENAME
2960  printf("c_memory cMemoryFile: MOVE [%s]\r\n",Buffer);
2961 #endif
2962 
2963  if (stat(DestinationBuf,&FileStatus) == 0)
2964  { // Exist
2965 
2966  cMemoryDeleteSubFolders(DestinationBuf);
2967 #ifdef DEBUG_TRACE_FILENAME
2968  printf(" c_memory cMemoryFile: remove [%s]\r\n",DestinationBuf);
2969 #endif
2970  sync();
2971  }
2972 
2973  system(Buffer);
2974  sync();
2975  SetUiUpdate();
2976  }
2977  }
2978 
2979  DspStat = NOBREAK;
2980  }
2981  break;
2982 
2983  case LOAD_IMAGE :
2984  {
2985  PrgNo = *(DATA16*)PrimParPointer();
2986  pFileName = (DATA8*)PrimParPointer();
2987  DspStat = FAILBREAK;
2988  ISize = 0;
2989  ImagePointer = 0;
2990 
2991  if (ProgramStatus(PrgNo) == STOPPED)
2992  {
2993  if (cMemoryCheckFilename((char*)pFileName,PathBuf,NameBuf,ExtBuf) == OK)
2994  { // Filename OK
2995 
2996  if (PathBuf[0] == 0)
2997  { // Default path
2998 
2999  snprintf(PathBuf,vmPATHSIZE,"%s/",DEFAULT_FOLDER);
3000  }
3001 
3002  if (ExtBuf[0] == 0)
3003  { // Default extension
3004 
3005  snprintf(ExtBuf,vmEXTSIZE,"%s",EXT_BYTECODE);
3006  }
3007 
3008  // Save path
3009  snprintf((char*)MemoryInstance.PathList[PrgNo],vmPATHSIZE,"%s",PathBuf);
3010 
3011  // Save name for run screen
3012  snprintf((char*)VMInstance.Program[PrgNo].Name,vmNAMESIZE,"%s",NameBuf);
3013 
3014  // Construct filename for open
3015  snprintf(FilenameBuf,vmFILENAMESIZE,"%s%s%s",PathBuf,NameBuf,ExtBuf);
3016 
3017 #ifdef DEBUG_TRACE_FILENAME
3018  printf("c_memory cMemoryFile: LOAD_IMAGE [%s]\r\n",FilenameBuf);
3019 #endif
3020  hFile = open(FilenameBuf,O_RDONLY);
3021 
3022  if (hFile >= MIN_HANDLE)
3023  {
3024  stat(FilenameBuf,&FileStatus);
3025  ISize = FileStatus.st_size;
3026 
3027  // allocate memory to contain the whole file:
3028  if (cMemoryAlloc(PrgNo,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pImage,&TmpHandle) == OK)
3029  {
3030  if (ISize == read(hFile,pImage,ISize))
3031  {
3032  ImagePointer = (DATA32)pImage;
3033  DspStat = NOBREAK;
3034  }
3035  }
3036 
3037  close(hFile);
3038  }
3039  *(DATA32*)PrimParPointer() = ISize;
3040  *(DATA32*)PrimParPointer() = ImagePointer;
3041  }
3042  else
3043  {
3044  PrimParPointer();
3045  PrimParPointer();
3046  }
3047  }
3048  else
3049  {
3050  PrimParPointer();
3051  PrimParPointer();
3052  }
3053  DspStat = NOBREAK;
3054  }
3055  break;
3056 
3057  case GET_POOL :
3058  {
3059  ISize = *(DATA32*)PrimParPointer();
3060  DspStat = FAILBREAK;
3061  TmpHandle = -1;
3062 
3063  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pImage,&TmpHandle) == OK)
3064  {
3065  ImagePointer = (DATA32)pImage;
3066  DspStat = NOBREAK;
3067  }
3068 
3069  *(DATA16*)PrimParPointer() = TmpHandle;
3070  *(DATA32*)PrimParPointer() = ImagePointer;
3071  }
3072  break;
3073 
3074  case GET_FOLDERS :
3075  {
3076  pFolderName = (DATA8*)PrimParPointer();
3077  *(DATA8*)PrimParPointer() = cMemoryFindSubFolders((char*)pFolderName);
3078 
3079  DspStat = NOBREAK;
3080  }
3081  break;
3082 
3083  case GET_SUBFOLDER_NAME :
3084  {
3085  pFolderName = (DATA8*)PrimParPointer();
3086  Item = *(DATA8*)PrimParPointer();
3087  Lng = *(DATA8*)PrimParPointer();
3088  pDestination = (DATA8*)PrimParPointer();
3089 
3090  cMemoryGetSubFolderName(Item,Lng,(char*)pFolderName,(char*)pDestination);
3091 
3092  DspStat = NOBREAK;
3093  }
3094  break;
3095 
3096  case DEL_SUBFOLDER :
3097  {
3098  pFolderName = (DATA8*)PrimParPointer();
3099  Item = *(DATA8*)PrimParPointer();
3100  cMemoryGetSubFolderName(Item,SUBFOLDERNAME_SIZE,(char*)pFolderName,PrgNamePath);
3101 
3102  snprintf(PrgNameBuf,MAX_FILENAME_SIZE,"%s%s",(char*)pFolderName,PrgNamePath);
3103 #ifdef DEBUG
3104  printf("Trying to delete %s\r\n",PrgNameBuf);
3105 #endif
3106  cMemoryDeleteSubFolders(PrgNameBuf);
3107 
3108  DspStat = NOBREAK;
3109  }
3110  break;
3111 
3112  case SET_LOG_SYNC_TIME :
3113  {
3114  MemoryInstance.SyncTime = *(DATA32*)PrimParPointer();
3115  MemoryInstance.SyncTick = *(DATA32*)PrimParPointer();
3116 
3117  DspStat = NOBREAK;
3118  }
3119  break;
3120 
3121  case GET_LOG_SYNC_TIME :
3122  {
3123  *(DATA32*)PrimParPointer() = MemoryInstance.SyncTime;
3124  *(DATA32*)PrimParPointer() = MemoryInstance.SyncTick;
3125 
3126  DspStat = NOBREAK;
3127  }
3128  break;
3129 
3130  case GET_ITEM :
3131  {
3132  pFolderName = (DATA8*)PrimParPointer();
3133  pFileName = (DATA8*)PrimParPointer();
3134  DspStat = NOBREAK;
3135 
3136  Items = cMemoryFindSubFolders((char*)pFolderName);
3137  Tmp = 0;
3138  Item = 0;
3139 
3140  while ((Items > 0) && (Item == 0))
3141  {
3142  Tmp++;
3143  cMemoryGetSubFolderName(Tmp,SUBFOLDERNAME_SIZE,(char*)pFolderName,(char*)PrgNamePath);
3144 #ifdef DEBUG
3145  printf("%s %s\r\n",(char*)pFileName,PrgNamePath);
3146 #endif
3147  if (strcmp((char*)pFileName,PrgNamePath) == 0)
3148  {
3149  Item = Tmp;
3150 #ifdef DEBUG
3151  printf("Found %i\r\n",Item);
3152 #endif
3153  }
3154  Items--;
3155  }
3156  *(DATA8*)PrimParPointer() = Item;
3157 
3158  }
3159  break;
3160 
3161  case GET_CACHE_FILES :
3162  {
3163  Items = 0;
3164  for (Tmp = 0;Tmp < CACHE_DEEPT;Tmp++)
3165  {
3166  if (MemoryInstance.Cache[Tmp][0])
3167  {
3168  Items++;
3169  }
3170  }
3171  *(DATA8*)PrimParPointer() = Items;
3172 #ifdef DEBUG
3173  printf("GET_CACHE_FILES %d\r\n",Items);
3174 #endif
3175  DspStat = NOBREAK;
3176  }
3177  break;
3178 
3179  case PUT_CACHE_FILE :
3180  {
3181  pFileName = (DATA8*)PrimParPointer();
3182 
3183 #ifdef DEBUG
3184  printf("PUT_CACHE_FILE %s\r\n",(char*)pFileName);
3185 #endif
3186  DspStat = NOBREAK;
3187 
3188  if (cMemoryCheckFilename((char*)pFileName,PathBuf,NameBuf,ExtBuf) == OK)
3189  { // Filename OK
3190 
3191  Item = 0;
3192  Tmp = 0;
3193  while ((Item < CACHE_DEEPT) && (Tmp == 0))
3194  {
3195  if (strcmp((char*)MemoryInstance.Cache[Item],(char*)pFileName) == 0)
3196  {
3197  Tmp = 1;
3198  }
3199  else
3200  {
3201  Item++;
3202  }
3203  }
3204  while (Item < (CACHE_DEEPT - 1))
3205  {
3206  strcpy((char*)MemoryInstance.Cache[Item],(char*)MemoryInstance.Cache[Item + 1]);
3207  Item++;
3208  }
3209  MemoryInstance.Cache[Item][0] = 0;
3210 
3211  for (Item = (CACHE_DEEPT - 1);Item > 0;Item--)
3212  {
3213  strcpy((char*)MemoryInstance.Cache[Item],(char*)MemoryInstance.Cache[Item - 1]);
3214  }
3215  strcpy((char*)MemoryInstance.Cache[Item],(char*)pFileName);
3216  }
3217  }
3218  break;
3219 
3220  case DEL_CACHE_FILE :
3221  {
3222  pFileName = (DATA8*)PrimParPointer();
3223 
3224  cMemoryDeleteCacheFile((char*)pFileName);
3225 
3226  DspStat = NOBREAK;
3227  }
3228  break;
3229 
3230  case GET_CACHE_FILE :
3231  {
3232  Item = *(DATA8*)PrimParPointer();
3233  Lng = *(DATA8*)PrimParPointer();
3234  pDestination = (DATA8*)PrimParPointer();
3235 
3236  DspStat = FAILBREAK;
3237  if ((Item > 0) && (Item <= CACHE_DEEPT))
3238  {
3239  if (MemoryInstance.Cache[Item - 1])
3240  {
3241  snprintf((char*)pDestination,Lng,"%s",MemoryInstance.Cache[Item - 1]);
3242  DspStat = NOBREAK;
3243  }
3244  }
3245  }
3246  break;
3247 
3248  default :
3249  {
3250  DspStat = FAILBREAK;
3251  }
3252  break;
3253 
3254  }
3255 
3256  if (Error)
3257  {
3258  if (!LogErrorNumberExists(Error))
3259  {
3260  LogErrorNumber(Error);
3261  }
3262  }
3263 
3264  if (DspStat == BUSYBREAK)
3265  { // Rewind IP
3266 
3267  SetObjectIp(TmpIp - 1);
3268  }
3269  SetDispatchStatus(DspStat);
3270 }
3271 
3272 
3392 void cMemoryArray(void)
3393 {
3394  DSPSTAT DspStat = BUSYBREAK;
3395  PRGID TmpPrgId;
3396  PRGID PrgId;
3397  IP TmpIp;
3398  DATA8 Cmd;
3399  HANDLER TmpHandle;
3400  HANDLER hSource;
3401  HANDLER hDest;
3402  void *pTmp;
3403  void *pSource;
3404  void *pDest;
3405  DATA32 Elements;
3406  DATA32 Index;
3407  DATA32 ISize;
3408  DATA32 ElementSize;
3409  DATA8 *pData8;
3410  DATA16 *pData16;
3411  DATA32 *pData32;
3412  DATAF *pDataF;
3413  DATA8 *pDData8;
3414  DATA8 Data8;
3415  DATA16 Data16;
3416  DATA32 Data32;
3417  DATAF DataF;
3418  DATA32 Bytes;
3419  void *pArray;
3420 
3421  TmpPrgId = CurrentProgramId();
3422  TmpIp = GetObjectIp();
3423 
3424  Cmd = *(DATA8*)PrimParPointer();
3425 
3426  switch (Cmd)
3427  { // Function
3428 
3429  case CREATE8 :
3430  {
3431  Elements = *(DATA32*)PrimParPointer();
3432 
3433  if (Elements < MIN_ARRAY_ELEMENTS)
3434  {
3435  Elements = MIN_ARRAY_ELEMENTS;
3436  }
3437 
3438  ElementSize = sizeof(DATA8);
3439  ISize = Elements * ElementSize + sizeof(DESCR);
3440 
3441  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pTmp,&TmpHandle) == OK)
3442  {
3443  (*(DESCR*)pTmp).Type = DATA_8;
3444  (*(DESCR*)pTmp).ElementSize = (DATA8)ElementSize;
3445  (*(DESCR*)pTmp).Elements = Elements;
3446 
3447  DspStat = NOBREAK;
3448  }
3449  else
3450  {
3451  DspStat = FAILBREAK;
3452  }
3453 
3454  *(HANDLER*)PrimParPointer() = (HANDLER)TmpHandle;
3455  }
3456  break;
3457 
3458  case CREATE16 :
3459  {
3460  Elements = *(DATA32*)PrimParPointer();
3461  ElementSize = sizeof(DATA16);
3462  ISize = Elements * ElementSize + sizeof(DESCR);
3463 
3464  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pTmp,&TmpHandle) == OK)
3465  {
3466  (*(DESCR*)pTmp).Type = DATA_16;
3467  (*(DESCR*)pTmp).ElementSize = (DATA8)ElementSize;
3468  (*(DESCR*)pTmp).Elements = Elements;
3469 
3470  DspStat = NOBREAK;
3471  }
3472  else
3473  {
3474  DspStat = FAILBREAK;
3475  }
3476 
3477  *(HANDLER*)PrimParPointer() = (HANDLER)TmpHandle;
3478  }
3479  break;
3480 
3481  case CREATE32 :
3482  {
3483  Elements = *(DATA32*)PrimParPointer();
3484  ElementSize = sizeof(DATA32);
3485  ISize = Elements * ElementSize + sizeof(DESCR);
3486 
3487  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pTmp,&TmpHandle) == OK)
3488  {
3489  (*(DESCR*)pTmp).Type = DATA_32;
3490  (*(DESCR*)pTmp).ElementSize = (DATA8)ElementSize;
3491  (*(DESCR*)pTmp).Elements = Elements;
3492 
3493  DspStat = NOBREAK;
3494  }
3495  else
3496  {
3497  DspStat = FAILBREAK;
3498  }
3499 
3500  *(HANDLER*)PrimParPointer() = (HANDLER)TmpHandle;
3501  }
3502  break;
3503 
3504  case CREATEF :
3505  {
3506  Elements = *(DATA32*)PrimParPointer();
3507  ElementSize = sizeof(DATAF);
3508  ISize = Elements * ElementSize + sizeof(DESCR);
3509 
3510  if (cMemoryAlloc(TmpPrgId,POOL_TYPE_MEMORY,(GBINDEX)ISize,(void**)&pTmp,&TmpHandle) == OK)
3511  {
3512  (*(DESCR*)pTmp).Type = DATA_F;
3513  (*(DESCR*)pTmp).ElementSize = (DATA8)ElementSize;
3514  (*(DESCR*)pTmp).Elements = Elements;
3515 
3516  DspStat = NOBREAK;
3517  }
3518  else
3519  {
3520  DspStat = FAILBREAK;
3521  }
3522 
3523  *(HANDLER*)PrimParPointer() = (HANDLER)TmpHandle;
3524  }
3525  break;
3526 
3527  case SIZE :
3528  {
3529  TmpHandle = *(HANDLER*)PrimParPointer();
3530  Elements = 0;
3531  TmpPrgId = CurrentProgramId();
3532 
3533  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3534  {
3535  Elements = (*(DESCR*)pTmp).Elements;
3536  }
3537 
3538  *(DATA32*)PrimParPointer() = Elements;
3539  DspStat = NOBREAK;
3540  }
3541  break;
3542 
3543  case RESIZE :
3544  {
3545  TmpHandle = *(HANDLER*)PrimParPointer();
3546  Elements = *(DATA32*)PrimParPointer();
3547 
3548  if (cMemoryResize(TmpPrgId,TmpHandle,Elements) != NULL)
3549  {
3550  DspStat = NOBREAK;
3551  }
3552  else
3553  {
3554  DspStat = FAILBREAK;
3555  }
3556  }
3557  break;
3558 
3559  case DELETE :
3560  {
3561  TmpHandle = *(HANDLER*)PrimParPointer();
3562  cMemoryFreeHandle(TmpPrgId,TmpHandle);
3563  DspStat = NOBREAK;
3564  }
3565  break;
3566 
3567  case FILL :
3568  {
3569  TmpPrgId = CurrentProgramId();
3570  TmpHandle = *(HANDLER*)PrimParPointer();
3571 
3572  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3573  {
3574  pArray = (*(DESCR*)pTmp).pArray;
3575  Elements = (*(DESCR*)pTmp).Elements;
3576  Index = 0;
3577  switch ((*(DESCR*)pTmp).Type)
3578  {
3579  case DATA_8 :
3580  {
3581  Data8 = *(DATA8*)PrimParPointer();
3582  pData8 = (DATA8*)pArray;
3583 
3584  while (Index < Elements)
3585  {
3586  pData8[Index] = Data8;
3587  Index++;
3588  }
3589  DspStat = NOBREAK;
3590  }
3591  break;
3592 
3593  case DATA_16 :
3594  {
3595  Data16 = *(DATA16*)PrimParPointer();
3596  pData16 = (DATA16*)pArray;
3597 
3598  while (Index < Elements)
3599  {
3600  pData16[Index] = Data16;
3601  Index++;
3602  }
3603  DspStat = NOBREAK;
3604  }
3605  break;
3606 
3607  case DATA_32 :
3608  {
3609  Data32 = *(DATA32*)PrimParPointer();
3610  pData32 = (DATA32*)pArray;
3611 
3612  while (Index < Elements)
3613  {
3614  pData32[Index] = Data32;
3615  Index++;
3616  }
3617  DspStat = NOBREAK;
3618  }
3619  break;
3620 
3621  case DATA_F :
3622  {
3623  DataF = *(DATAF*)PrimParPointer();
3624  pDataF = (DATAF*)pArray;
3625 
3626  while (Index < Elements)
3627  {
3628  pDataF[Index] = DataF;
3629  Index++;
3630  }
3631  DspStat = NOBREAK;
3632  }
3633  break;
3634 
3635  }
3636  }
3637  }
3638  break;
3639 
3640  case COPY :
3641  {
3642  hSource = *(HANDLER*)PrimParPointer();
3643  hDest = *(HANDLER*)PrimParPointer();
3644 
3645  DspStat = FAILBREAK;
3646  if (cMemoryGetPointer(TmpPrgId,hSource,&pSource) == OK)
3647  {
3648  if (cMemoryGetPointer(TmpPrgId,hDest,&pDest) == OK)
3649  {
3650  if ((*(DESCR*)pSource).Type == (*(DESCR*)pDest).Type)
3651  {
3652  Elements = (*(DESCR*)pSource).Elements;
3653  DspStat = NOBREAK;
3654 
3655  if (cMemoryResize(TmpPrgId,hDest,Elements) == NULL)
3656  {
3657  DspStat = FAILBREAK;
3658  }
3659  if (DspStat == NOBREAK)
3660  {
3661  if (cMemoryGetPointer(TmpPrgId,hDest,&pDest) == OK)
3662  {
3663  ISize = Elements * (*(DESCR*)pSource).ElementSize;
3664  memcpy((*(DESCR*)pDest).pArray,(*(DESCR*)pSource).pArray,ISize);
3665  }
3666  else
3667  {
3668  DspStat = FAILBREAK;
3669  }
3670  }
3671  }
3672  }
3673  }
3674  }
3675  break;
3676 
3677  case INIT8 :
3678  {
3679  TmpHandle = *(HANDLER*)PrimParPointer();
3680  Index = *(DATA32*)PrimParPointer();
3681  Elements = *(DATA32*)PrimParPointer();
3682 
3683  DspStat = FAILBREAK;
3684 
3685  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3686  {
3687  if ((Index >= 0) && ((Index + Elements) <= (*(DESCR*)pTmp).Elements))
3688  {
3689  pArray = (*(DESCR*)pTmp).pArray;
3690  pData8 = (DATA8*)pArray;
3691 
3692  while (Elements)
3693  {
3694  pData8[Index] = *(DATA8*)PrimParPointer();
3695  Elements--;
3696  Index++;
3697  }
3698  DspStat = NOBREAK;
3699  }
3700  }
3701  }
3702  break;
3703 
3704  case INIT16 :
3705  {
3706  TmpHandle = *(HANDLER*)PrimParPointer();
3707  Index = *(DATA32*)PrimParPointer();
3708  Elements = *(DATA32*)PrimParPointer();
3709 
3710  DspStat = FAILBREAK;
3711 
3712  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3713  {
3714  if ((Index >= 0) && ((Index + Elements) <= (*(DESCR*)pTmp).Elements))
3715  {
3716  pArray = (*(DESCR*)pTmp).pArray;
3717  pData16 = (DATA16*)pArray;
3718 
3719  while (Elements)
3720  {
3721  pData16[Index] = *(DATA16*)PrimParPointer();
3722  Elements--;
3723  Index++;
3724  }
3725  DspStat = NOBREAK;
3726  }
3727  }
3728  }
3729  break;
3730 
3731  case INIT32 :
3732  {
3733  TmpHandle = *(HANDLER*)PrimParPointer();
3734  Index = *(DATA32*)PrimParPointer();
3735  Elements = *(DATA32*)PrimParPointer();
3736 
3737  DspStat = FAILBREAK;
3738 
3739  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3740  {
3741  if ((Index >= 0) && ((Index + Elements) <= (*(DESCR*)pTmp).Elements))
3742  {
3743  pArray = (*(DESCR*)pTmp).pArray;
3744  pData32 = (DATA32*)pArray;
3745 
3746  while (Elements)
3747  {
3748  pData32[Index] = *(DATA32*)PrimParPointer();
3749  Elements--;
3750  Index++;
3751  }
3752  DspStat = NOBREAK;
3753  }
3754  }
3755  }
3756  break;
3757 
3758  case INITF :
3759  {
3760  TmpHandle = *(HANDLER*)PrimParPointer();
3761  Index = *(DATA32*)PrimParPointer();
3762  Elements = *(DATA32*)PrimParPointer();
3763 
3764  DspStat = FAILBREAK;
3765 
3766  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3767  {
3768  if ((Index >= 0) && ((Index + Elements) <= (*(DESCR*)pTmp).Elements))
3769  {
3770  pArray = (*(DESCR*)pTmp).pArray;
3771  pDataF = (DATAF*)pArray;
3772 
3773  while (Elements)
3774  {
3775  pDataF[Index] = *(DATAF*)PrimParPointer();
3776  Elements--;
3777  Index++;
3778  }
3779  DspStat = NOBREAK;
3780  }
3781  }
3782  }
3783  break;
3784 
3785  case READ_CONTENT :
3786  {
3787  PrgId = *(DATA16*)PrimParPointer();
3788  TmpHandle = *(DATA16*)PrimParPointer();
3789  Index = *(DATA32*)PrimParPointer();
3790  Bytes = *(DATA32*)PrimParPointer();
3791  pDData8 = (DATA8*)PrimParPointer();
3792 
3793  DspStat = FAILBREAK;
3794 
3795  if (PrgId == (PRGID)CURRENT_SLOT)
3796  {
3797  PrgId = TmpPrgId;
3798  }
3799 
3800  if (cMemoryGetPointer(PrgId,TmpHandle,&pTmp) == OK)
3801  {
3802  if (VMInstance.Handle >= 0)
3803  {
3804  pDData8 = (DATA8*)VmMemoryResize(VMInstance.Handle,Bytes);
3805  }
3806 
3807  ISize = (*(DESCR*)pTmp).Elements * (DATA32)((*(DESCR*)pTmp).ElementSize);
3808 
3809  if ((Index >= 0) && (pDData8 != NULL))
3810  {
3811  pArray = (*(DESCR*)pTmp).pArray;
3812 
3813  pData8 = (DATA8*)pArray;
3814  Data32 = 0;
3815 
3816  while ((Data32 < Bytes) && (Index < ISize))
3817  {
3818  pDData8[Data32] = pData8[Index];
3819  Data32++;
3820  Index++;
3821  }
3822  while (Data32 < Bytes)
3823  {
3824  pDData8[Data32] = 0;
3825  Data32++;
3826  }
3827  DspStat = NOBREAK;
3828  }
3829  }
3830  }
3831  break;
3832 
3833  case WRITE_CONTENT :
3834  {
3835  PrgId = *(DATA16*)PrimParPointer();
3836  TmpHandle = *(DATA16*)PrimParPointer();
3837  Index = *(DATA32*)PrimParPointer();
3838  Bytes = *(DATA32*)PrimParPointer();
3839  pDData8 = (DATA8*)PrimParPointer();
3840 
3841  DspStat = FAILBREAK;
3842 
3843 #ifdef DEBUG
3844  printf("ARRAY WRITE_CONTENT CP=%d PP=%d\r\n",TmpPrgId,PrgId);
3845 #endif
3846 
3847  if (PrgId == (PRGID)CURRENT_SLOT)
3848  {
3849  PrgId = TmpPrgId;
3850  }
3851 
3852  if (cMemoryGetPointer(PrgId,TmpHandle,&pTmp) == OK)
3853  {
3854  ElementSize = (DATA32)(*(DESCR*)pTmp).ElementSize;
3855  if (ElementSize)
3856  {
3857  Elements = (Index + Bytes + (ElementSize - 1)) / ElementSize;
3858  ISize = Elements * ElementSize;
3859 
3860  pTmp = cMemoryResize(PrgId,TmpHandle,Elements);
3861  if (pTmp != NULL)
3862  {
3863  if ((Index >= 0) && (pDData8 != NULL))
3864  {
3865  pData8 = (DATA8*)pTmp;
3866  Data32 = 0;
3867 
3868  while ((Data32 < Bytes) && (Index < ISize))
3869  {
3870  pData8[Index] = pDData8[Data32];
3871  Data32++;
3872  Index++;
3873  }
3874  DspStat = NOBREAK;
3875  }
3876  }
3877  }
3878  }
3879  }
3880  break;
3881 
3882  case READ_SIZE :
3883  {
3884  PrgId = *(DATA16*)PrimParPointer();
3885  TmpHandle = *(DATA16*)PrimParPointer();
3886 
3887  Bytes = 0;
3888  DspStat = FAILBREAK;
3889 
3890  if (PrgId == (PRGID)CURRENT_SLOT)
3891  {
3892  PrgId = TmpPrgId;
3893  }
3894 
3895  if (cMemoryGetPointer(PrgId,TmpHandle,&pTmp) == OK)
3896  {
3897  Bytes = (*(DESCR*)pTmp).Elements * (DATA32)((*(DESCR*)pTmp).ElementSize);
3898  }
3899 
3900  *(DATA32*)PrimParPointer() = Bytes;
3901  DspStat = NOBREAK;
3902  }
3903  break;
3904 
3905  }
3906 
3907 
3908  if (DspStat == BUSYBREAK)
3909  { // Rewind IP
3910 
3911  SetObjectIp(TmpIp - 1);
3912  }
3913  SetDispatchStatus(DspStat);
3914 }
3915 
3916 
3936 {
3937  DSPSTAT DspStat = FAILBREAK;
3938  PRGID TmpPrgId;
3939  HANDLER TmpHandle;
3940  void *pTmp;
3941  void *pValue;
3942  DESCR *pDescr;
3943  DATA32 Elements;
3944  DATA32 Index;
3945  void *pArray;
3946  DATA8 *pData8;
3947  DATA16 *pData16;
3948  DATA32 *pData32;
3949  DATAF *pDataF;
3950 
3951  TmpPrgId = CurrentProgramId();
3952  TmpHandle = *(HANDLER*)PrimParPointer();
3953  Index = *(DATA32*)PrimParPointer();
3954  pValue = PrimParPointer();
3955 
3956  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3957  {
3958  pDescr = (DESCR*)pTmp;
3959  if (Index >= 0)
3960  {
3961  Elements = Index + 1;
3962 
3963  DspStat = NOBREAK;
3964  if (Elements > (*pDescr).Elements)
3965  {
3966  if (cMemoryResize(TmpPrgId,TmpHandle,Elements) == NULL)
3967  {
3968  DspStat = FAILBREAK;
3969  }
3970  }
3971  if (DspStat == NOBREAK)
3972  {
3973  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
3974  {
3975  pDescr = (DESCR*)pTmp;
3976  pArray = (*pDescr).pArray;
3977 #ifdef DEBUG
3978  printf(" Write P=%1u H=%1u I=%8lu A=%8p\r\n",(unsigned int)TmpPrgId,(unsigned int)TmpHandle,(unsigned long)Index,pArray);
3979 #endif
3980  switch ((*pDescr).Type)
3981  {
3982  case DATA_8 :
3983  {
3984  pData8 = (DATA8*)pArray;
3985  pData8[Index] = *(DATA8*)pValue;
3986  DspStat = NOBREAK;
3987  }
3988  break;
3989 
3990  case DATA_16 :
3991  {
3992  pData16 = (DATA16*)pArray;
3993  pData16[Index] = *(DATA16*)pValue;
3994  DspStat = NOBREAK;
3995  }
3996  break;
3997 
3998  case DATA_32 :
3999  {
4000  pData32 = (DATA32*)pArray;
4001  pData32[Index] = *(DATA32*)pValue;
4002  DspStat = NOBREAK;
4003  }
4004  break;
4005 
4006  case DATA_F :
4007  {
4008  pDataF = (DATAF*)pArray;
4009  pDataF[Index] = *(DATAF*)pValue;
4010  DspStat = NOBREAK;
4011  }
4012  break;
4013 
4014  }
4015  }
4016  }
4017  }
4018  }
4019  if (DspStat != NOBREAK)
4020  {
4021 #ifdef DEBUG
4022  printf(" WR ERR P=%1u H=%1u I=%8lu\r\n",(unsigned int)TmpPrgId,(unsigned int)TmpHandle,(unsigned long)Index);
4023 #endif
4024  SetDispatchStatus(DspStat);
4025  }
4026 }
4027 
4028 
4048 {
4049  DSPSTAT DspStat = FAILBREAK;
4050  PRGID TmpPrgId;
4051  HANDLER TmpHandle;
4052  void *pTmp;
4053  DATA32 Index;
4054  void *pArray;
4055  DATA8 *pData8;
4056  DATA16 *pData16;
4057  DATA32 *pData32;
4058  DATAF *pDataF;
4059 
4060  TmpPrgId = CurrentProgramId();
4061  TmpHandle = *(HANDLER*)PrimParPointer();
4062  Index = *(DATA32*)PrimParPointer();
4063 
4064  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
4065  {
4066  if ((Index >= 0) && (Index < (*(DESCR*)pTmp).Elements))
4067  {
4068  pArray = (*(DESCR*)pTmp).pArray;
4069 #ifdef DEBUG
4070  printf(" Read P=%1u H=%1u I=%8lu A=%8p\r\n",(unsigned int)TmpPrgId,(unsigned int)TmpHandle,(unsigned long)Index,pArray);
4071 #endif
4072  switch ((*(DESCR*)pTmp).Type)
4073  {
4074  case DATA_8 :
4075  {
4076  pData8 = (DATA8*)pArray;
4077  *(DATA8*)PrimParPointer() = pData8[Index];
4078  DspStat = NOBREAK;
4079  }
4080  break;
4081 
4082  case DATA_16 :
4083  {
4084  pData16 = (DATA16*)pArray;
4085  *(DATA16*)PrimParPointer() = pData16[Index];
4086  DspStat = NOBREAK;
4087  }
4088  break;
4089 
4090  case DATA_32 :
4091  {
4092  pData32 = (DATA32*)pArray;
4093  *(DATA32*)PrimParPointer() = pData32[Index];
4094  DspStat = NOBREAK;
4095  }
4096  break;
4097 
4098  case DATA_F :
4099  {
4100  pDataF = (DATAF*)pArray;
4101  *(DATAF*)PrimParPointer() = pDataF[Index];
4102  DspStat = NOBREAK;
4103  }
4104  break;
4105 
4106  }
4107  }
4108  }
4109  if (DspStat != NOBREAK)
4110  {
4111  PrimParAdvance();
4112  SetDispatchStatus(DspStat);
4113  }
4114 }
4115 
4116 
4135 {
4136  DSPSTAT DspStat = FAILBREAK;
4137  PRGID TmpPrgId;
4138  HANDLER TmpHandle;
4139  void *pTmp;
4140  void *pValue;
4141  DESCR *pDescr;
4142  DATA32 Elements;
4143  DATA32 Index;
4144  void *pArray;
4145  DATA8 *pData8;
4146  DATA16 *pData16;
4147  DATA32 *pData32;
4148  DATAF *pDataF;
4149 
4150  TmpPrgId = CurrentProgramId();
4151  TmpHandle = *(HANDLER*)PrimParPointer();
4152  pValue = PrimParPointer();
4153 
4154  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
4155  {
4156  pDescr = (DESCR*)pTmp;
4157  Index = (*pDescr).Elements;
4158  Elements = Index + 1;
4159 
4160  DspStat = NOBREAK;
4161  if (Elements > (*pDescr).Elements)
4162  {
4163  if (cMemoryResize(TmpPrgId,TmpHandle,Elements) == NULL)
4164  {
4165  DspStat = FAILBREAK;
4166  }
4167  }
4168  if (DspStat == NOBREAK)
4169  {
4170  if (cMemoryGetPointer(TmpPrgId,TmpHandle,&pTmp) == OK)
4171  {
4172  pDescr = (DESCR*)pTmp;
4173  pArray = (*pDescr).pArray;
4174 #ifdef DEBUG
4175  printf(" Append P=%1u H=%1u I=%8lu A=%8p",(unsigned int)TmpPrgId,(unsigned int)TmpHandle,(unsigned long)Index,pArray);
4176 #endif
4177  switch ((*pDescr).Type)
4178  {
4179  case DATA_8 :
4180  {
4181 #ifdef DEBUG
4182  printf(" V=%d",(int)*(DATA8*)pValue);
4183 #endif
4184  pData8 = (DATA8*)pArray;
4185  pData8[Index] = *(DATA8*)pValue;
4186  DspStat = NOBREAK;
4187  }
4188  break;
4189 
4190  case DATA_16 :
4191  {
4192 #ifdef DEBUG
4193  printf(" V=%d",(int)*(DATA16*)pValue);
4194 #endif
4195  pData16 = (DATA16*)pArray;
4196  pData16[Index] = *(DATA16*)pValue;
4197  DspStat = NOBREAK;
4198  }
4199  break;
4200 
4201  case DATA_32 :
4202  {
4203 #ifdef DEBUG
4204  printf(" V=%d",(int)*(DATA32*)pValue);
4205 #endif
4206  pData32 = (DATA32*)pArray;
4207  pData32[Index] = *(DATA32*)pValue;
4208  DspStat = NOBREAK;
4209  }
4210  break;
4211 
4212  case DATA_F :
4213  {
4214 #ifdef DEBUG
4215  printf(" V=%f",*(DATAF*)pValue);
4216 #endif
4217  pDataF = (DATAF*)pArray;
4218  pDataF[Index] = *(DATAF*)pValue;
4219  DspStat = NOBREAK;
4220  }
4221  break;
4222 
4223  }
4224 #ifdef DEBUG
4225  printf("\r\n");
4226 #endif
4227  }
4228  }
4229  }
4230  if (DspStat != NOBREAK)
4231  {
4232 #ifdef DEBUG
4233  printf(" WR ERR P=%1u H=%1u I=%8lu\r\n",(unsigned int)TmpPrgId,(unsigned int)TmpHandle,(unsigned long)Index);
4234 #endif
4235  SetDispatchStatus(DspStat);
4236  }
4237 }
4238 
4239 
4257 void cMemoryUsage(void)
4258 {
4259  DATA32 Total;
4260  DATA32 Free;
4261 
4262  cMemoryGetUsage(&Total,&Free,0);
4263 
4264  if (Total < 0)
4265  {
4266  Total = 0;
4267  }
4268  if (Free < 0)
4269  {
4270  Free = 0;
4271  }
4272 
4273  *(DATA32*)PrimParPointer() = Total;
4274  *(DATA32*)PrimParPointer() = Free;
4275 
4276 }
4277 
4278 
4348 {
4349  PRGID TmpPrgId;
4350  DATA8 Cmd;
4351  DATA8 Tmp;
4352  struct stat FileStatus;
4353  char Filename[MAX_FILENAME_SIZE];
4354  char Folder[MAX_FILENAME_SIZE];
4355  char Name[MAX_FILENAME_SIZE];
4356  char Ext[MAX_FILENAME_SIZE];
4357  char Buffer[2 * MAX_FILENAME_SIZE + 32];
4358  DATA8 Length;
4359  DATA8 *pFilename;
4360  DATA8 *pFolder;
4361  DATA8 *pName;
4362  DATA8 *pExt;
4363  HANDLER hFilename;
4364  HANDLER hFolder;
4365  HANDLER hName;
4366  HANDLER hExt;
4367  DATA32 Lng;
4368  DATA32 Size;
4369  DATA32 Files;
4370 
4371  TmpPrgId = CurrentProgramId();
4372  Cmd = *(DATA8*)PrimParPointer();
4373 
4374  switch (Cmd)
4375  { // Function
4376 
4377  case EXIST :
4378  {
4379  pFilename = (DATA8*)PrimParPointer();
4380  cMemoryFilename(TmpPrgId,(char*)pFilename,"",MAX_FILENAME_SIZE,Filename);
4381 
4382  Tmp = 0;
4383  if (stat(Filename,&FileStatus) == 0)
4384  {
4385  Tmp = 1;
4386  }
4387 #ifdef DEBUG_TRACE_FILENAME
4388  printf("c_memory cMemoryFileName: EXIST [%s] = %d\r\n",Filename,Tmp);
4389 #endif
4390  *(DATA8*)PrimParPointer() = Tmp;
4391  }
4392  break;
4393 
4394  case TOTALSIZE :
4395  {
4396  pFilename = (DATA8*)PrimParPointer();
4397  cMemoryFilename(TmpPrgId,(char*)pFilename,"",MAX_FILENAME_SIZE,Filename);
4398  Size = cMemoryFindSize((char*)Filename,&Files);
4399 
4400  *(DATA32*)PrimParPointer() = Files;
4401  *(DATA32*)PrimParPointer() = Size;
4402  }
4403  break;
4404 
4405  case SPLIT :
4406  {
4407  pFilename = (DATA8*)PrimParPointer();
4408  Length = *(DATA8*)PrimParPointer();
4409  pFolder = (DATA8*)PrimParPointer();
4410  hFolder = VMInstance.Handle;
4411  pName = (DATA8*)PrimParPointer();
4412  hName = VMInstance.Handle;
4413  pExt = (DATA8*)PrimParPointer();
4414  hExt = VMInstance.Handle;
4415 
4416  Tmp = Length;
4417 
4418  // Split pFilename
4419  FindName((char*)pFilename,Folder,Name,Ext);
4420 
4421  // Make pFolder
4422  Length = Tmp;
4423  if (hFolder >= 0)
4424  {
4425  Lng = strlen(Folder) + 1;
4426  if (Lng > MIN_ARRAY_ELEMENTS)
4427  {
4428  pFolder = (DATA8*)VmMemoryResize(hFolder,Lng);
4429  }
4430  Length = (DATA8)Lng;
4431  }
4432  snprintf((char*)pFolder,(int)Length,"%s",Folder);
4433 
4434  // Make pName
4435  Length = Tmp;
4436  if (hName >= 0)
4437  {
4438  Lng = strlen(Name) + 1;
4439  if (Lng > MIN_ARRAY_ELEMENTS)
4440  {
4441  pName = (DATA8*)VmMemoryResize(hName,Lng);
4442  }
4443  Length = (DATA8)Lng;
4444  }
4445  snprintf((char*)pName,(int)Length,"%s",Name);
4446 
4447  // Make pExt
4448  Length = Tmp;
4449  if (hExt >= 0)
4450  {
4451  Lng = strlen(Ext) + 1;
4452  if (Lng > MIN_ARRAY_ELEMENTS)
4453  {
4454  pExt = (DATA8*)VmMemoryResize(hExt,Lng);
4455  }
4456  Length = (DATA8)Lng;
4457  }
4458  snprintf((char*)pExt,(int)Length,"%s",Ext);
4459 
4460  }
4461  break;
4462 
4463  case MERGE :
4464  {
4465  pFolder = (DATA8*)PrimParPointer();
4466  pName = (DATA8*)PrimParPointer();
4467  pExt = (DATA8*)PrimParPointer();
4468  Length = *(DATA8*)PrimParPointer();
4469  pFilename = (DATA8*)PrimParPointer();
4470  hFilename = VMInstance.Handle;
4471 
4472  // Merge pFolder, pName and pExt
4473  snprintf(Filename,MAX_FILENAME_SIZE,"%s/%s%s",pFolder,pName,pExt);
4474 
4475  // Make pFilename
4476  if (hFilename >= 0)
4477  {
4478  Lng = strlen(Filename) + 1;
4479  if (Lng > MIN_ARRAY_ELEMENTS)
4480  {
4481  pFilename = (DATA8*)VmMemoryResize(hFilename,Lng);
4482  }
4483  Length = (DATA8)Lng;
4484  }
4485  snprintf((char*)pFilename,(int)Length,"%s",Filename);
4486  }
4487  break;
4488 
4489  case CHECK :
4490  {
4491  Tmp = 0;
4492  pFilename = (DATA8*)PrimParPointer();
4493  if (cMemoryCheckFilename((char*)pFilename,NULL,NULL,NULL) == OK)
4494  {
4495  Tmp = 1;
4496  }
4497 
4498  *(DATA8*)PrimParPointer() = Tmp;
4499  }
4500  break;
4501 
4502  case PACK :
4503  {
4504  pName = (DATA8*)PrimParPointer();
4505 
4506  // Split pFilename
4507  FindName((char*)pName,Folder,Name,Ext);
4508 
4509  snprintf(Buffer,2 * MAX_FILENAME_SIZE + 32,"tar -cz -f %s%s%s -C %s %s%s &> /dev/null",Folder,Name,vmEXT_ARCHIVE,Folder,Name,Ext);
4510  system(Buffer);
4511  sync();
4512  }
4513  break;
4514 
4515  case UNPACK :
4516  {
4517  pName = (DATA8*)PrimParPointer();
4518 
4519  // Split pFilename
4520  FindName((char*)pName,Folder,Name,Ext);
4521 
4522  snprintf(Buffer,2 * MAX_FILENAME_SIZE + 32,"tar -xz -f %s%s%s -C %s &> /dev/null",Folder,Name,vmEXT_ARCHIVE,Folder);
4523  system(Buffer);
4524  sync();
4525  }
4526  break;
4527 
4528  case GET_FOLDERNAME :
4529  {
4530  Length = *(DATA8*)PrimParPointer();
4531  pFilename = (DATA8*)PrimParPointer();
4532  hFilename = VMInstance.Handle;
4533 
4534  cMemoryGetResourcePath(TmpPrgId,(char*)Filename,MAX_FILENAME_SIZE);
4535  Lng = strlen(Filename);
4536 
4537 
4538  if (Lng > 0)
4539  {
4540  if (Filename[Lng - 1] == '/')
4541  {
4542  Lng--;
4543  Filename[Lng] = 0;
4544  }
4545  }
4546 
4547  // Make pFilename
4548  if (hFilename >= 0)
4549  {
4550  Lng++;
4551  if (Lng > MIN_ARRAY_ELEMENTS)
4552  {
4553  pFilename = (DATA8*)VmMemoryResize(hFilename,Lng);
4554  }
4555  Length = (DATA8)Lng;
4556  }
4557  if (pFilename != NULL)
4558  {
4559  snprintf((char*)pFilename,(int)Length,"%s",Filename);
4560  }
4561  }
4562  break;
4563 
4564  }
4565 }
4566 
4567 
4568 //*****************************************************************************
DATA8 PathList[MAX_PROGRAMS][vmPATHSIZE]
Definition: c_memory.h:148
DATA8 LogErrorNumberExists(ERR Error)
Definition: lms2012.c:470
DATA32 MemorySize
Definition: lms2012.h:1480
DATA8 cMemoryFindFiles(char *pFolderName)
Definition: c_memory.c:1038
void SetDispatchStatus(DSPSTAT DspStat)
Set object (dispatch) status.
Definition: lms2012.c:256
#define POOL_TYPE_FILE
Definition: c_memory.h:106
char Char
Definition: tistdtypes.h:54
void PrimParAdvance(void)
Skip next encoded parameter from byte code stream.
Definition: lms2012.c:870
GBINDEX Size
Definition: c_memory.h:111
DSPSTAT cMemoryGetFileHandle(PRGID PrgId, char *pFileName, HANDLER *pHandle, DATA8 *pOpenForWrite)
Definition: c_memory.c:1155
RESULT cMemoryAlloc(PRGID PrgId, DATA8 Type, GBINDEX Size, void **pMemory, HANDLER *pHandle)
Definition: c_memory.c:174
RESULT cMemoryGetImage(DATA8 *pFileName, DATA16 Size, UBYTE *pBmp)
Definition: c_memory.c:1480
void cMemoryFile(void)
opFILE byte code
Definition: c_memory.c:2303
DATA8 NoOfFavourites[SORT_TYPES]
Definition: c_memory.c:1562
RESULT cMemoryInit(void)
Definition: c_memory.c:375
Break because of fail.
Definition: lms2012.h:674
RESULT cMemoryGetIcon(DATA8 *pFolderName, DATA8 Item, DATA32 *pImagePointer)
Definition: c_memory.c:1071
SWORD DATA16
VM Type for 2 byte signed value.
Definition: lmstypes.h:62
DATA32 SyncTick
Definition: c_memory.h:145
void LogErrorNumber(ERR Err)
Definition: lms2012.c:445
DATA8 Type
Definition: c_memory.c:1543
DSPSTAT cMemoryWriteFile(PRGID PrgId, HANDLER Handle, DATA32 Size, DATA8 Del, DATA8 *pSource)
Definition: c_memory.c:1301
void cMemoryArrayWrite(void)
opARRAY_WRITE byte code
Definition: c_memory.c:3935
DATA32 cMemoryFindSize(char *pFolderName, DATA32 *pFiles)
Definition: c_memory.c:951
SLONG DATA32
VM Type for 4 byte signed value.
Definition: lmstypes.h:63
#define MemoryInstance
Definition: c_memory.h:158
RESULT cMemoryGetMediaName(char *pChar, char *pName)
Definition: c_memory.c:1504
DATA8 Name[FILENAME_SIZE]
Definition: lms2012.h:762
RESULT cMemoryArraryPointer(PRGID PrgId, HANDLER Handle, void **pMemory)
Definition: c_memory.c:277
void cMemoryCloseFolder(PRGID PrgId, HANDLER *pHandle)
Definition: c_memory.c:2064
DIR * pDir
Definition: c_memory.c:1541
RESULT ConstructFilename(PRGID PrgId, char *pFilename, char *pName, char *pDefaultExt)
Definition: c_memory.c:633
#define KB
Definition: lms2012.h:553
void SetObjectIp(IP Ip)
Set current instruction pointer.
Definition: lms2012.c:309
#define EXT_PROGRAM
Rudolf program byte code file.
Definition: lms2012.h:228
DATA8 cMemoryFindType(char *pExt)
Definition: c_memory.c:794
DATA8 Cache[CACHE_DEEPT+1][vmFILENAMESIZE]
Definition: c_memory.h:151
char * pFavourites[SORT_TYPES][8]
Definition: c_memory.c:1578
void FindName(char *pSource, char *pPath, char *pName, char *pExt)
Definition: c_memory.c:496
void cMemoryFileName(void)
opFILENAME byte code
Definition: c_memory.c:4347
DATA16 HANDLER
Memory list index.
Definition: lmstypes.h:85
void * PrimParPointer(void)
Get next encoded parameter from byte code stream.
Definition: lms2012.c:694
void cMemoryDeleteSubFolders(char *pFolderName)
Definition: c_memory.c:911
#define EXT_BYTECODE
Rudolf byte code file.
Definition: lms2012.h:225
IP GetObjectIp(void)
Get current instruction pointer.
Definition: lms2012.c:298
DATA8 cMemoryGetCacheName(DATA8 Item, DATA8 MaxLength, char *pFileName, char *pName)
Definition: c_memory.c:986
void cMemoryArray(void)
opARRAY byte code
Definition: c_memory.c:3392
void cMemoryUsage(void)
opMEMORY_USAGE byte code
Definition: c_memory.c:4257
DATA32 SyncTime
Definition: c_memory.h:144
RESULT cMemoryCheckFilename(char *pFilename, char *pPath, char *pName, char *pExt)
Definition: c_memory.c:552
void cMemorySortList(FOLDER *pMemory)
Definition: c_memory.c:1671
RESULT cMemoryMalloc(void **ppMemory, DATA32 Size)
Definition: c_memory.c:140
DSPSTAT cMemoryFreeHandle(PRGID PrgId, HANDLER Handle)
Definition: c_memory.c:292
void setMemoryInstance(MEMORY_GLOBALS *_Instance)
Definition: c_memory.c:81
RESULT cMemoryExit(void)
Definition: c_memory.c:448
POOL pPoolList[MAX_PROGRAMS][MAX_HANDLES]
Definition: c_memory.h:149
#define UPDATE_MEMORY
Update memory size [mS].
Definition: lms2012.h:522
DATA32 MemoryFree
Definition: lms2012.h:1481
OBJSTAT ProgramStatus(PRGID PrgId)
Get program status.
Definition: lms2012.c:218
IMGDATA * IP
Instruction pointer type.
Definition: lmstypes.h:74
RESULT cMemoryRealloc(void *pOldMemory, void **ppMemory, DATA32 Size)
Definition: c_memory.c:160
RESULT cMemoryOpen(PRGID PrgId, GBINDEX Size, void **pMemory)
Definition: c_memory.c:426
DATA8 Sort
Definition: c_memory.c:1544
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
RESULT cMemoryGetPointer(PRGID PrgId, HANDLER Handle, void **pMemory)
Definition: c_memory.c:252
void cMemoryArrayRead(void)
opARRAY_READ byte code
Definition: c_memory.c:4047
ULONG GBINDEX
GlobalBytes index type.
Definition: lmstypes.h:79
DATA8 cMemoryGetSubFolderName(DATA8 Item, DATA8 MaxLength, char *pFolderName, char *pSubFolderName)
Definition: c_memory.c:852
DATA32 Elements
Definition: c_memory.h:119
Definition: d_pwm.c:329
DSPSTAT cMemoryOpenFile(PRGID PrgId, DATA8 Access, char *pFileName, HANDLER *pHandle, DATA32 *pSize)
Definition: c_memory.c:1219
void cMemoryArrayAppend(void)
opARRAY_APPEND byte code
Definition: c_memory.c:4134
DSPSTAT cMemoryCloseFile(PRGID PrgId, HANDLER Handle)
Definition: c_memory.c:1421
void cMemoryFreeProgram(PRGID PrgId)
Definition: c_memory.c:350
RESULT cMemoryClose(PRGID PrgId)
Definition: c_memory.c:437
DATA8 cMemoryFindSubFolders(char *pFolderName)
Definition: c_memory.c:763
RESULT cMemorySetItemText(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 *pText)
Definition: c_memory.c:1982
void * cMemoryResize(PRGID PrgId, HANDLER TmpHandle, DATA32 Elements)
Definition: c_memory.c:468
MEMORY_GLOBALS * gMemoryInstance
Definition: c_memory.c:79
RESULT cMemoryCheckOpenWrite(char *pFileName)
Definition: c_memory.c:1199
RESULT cMemoryGetItemName(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pName, DATA8 *pType, DATA8 *pPriority)
Definition: c_memory.c:1815
void cMemoryGetUsage(DATA32 *pTotal, DATA32 *pFree, DATA8 Force)
Definition: c_memory.c:104
void cMemoryFindLogName(PRGID PrgId, char *pName)
Definition: c_memory.c:1452
RESULT cMemoryGetItemText(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pText)
Definition: c_memory.c:1921
int FindDot(char *pString)
Definition: c_memory.c:670
int cMemorySort(void *ppFirst, void *ppSecond)
Definition: c_memory.c:719
RESULT ValidateString(DATA8 *pString, DATA8 Set)
Definition: lms2012.c:5694
void cMemoryFreePool(PRGID PrgId, void *pMemory)
Definition: c_memory.c:334
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
PRG Program[MAX_PROGRAMS]
Program[0] is the UI byte codes running.
Definition: lms2012.h:1431
#define EXT_TEXT
Rudolf text file.
Definition: lms2012.h:226
DATA8 cMemoryGetCacheFiles(void)
Definition: c_memory.c:1021
#define EXT_SOUND
Rudolf sound file.
Definition: lms2012.h:223
RESULT cMemoryGetItemIcon(PRGID PrgId, HANDLER Handle, DATA16 Item, HANDLER *pHandle, DATA32 *pImagePointer)
Definition: c_memory.c:1869
HANDLER Handle
Definition: lms2012.h:1474
FLOAT DATAF
VM Type for 4 byte floating point value.
Definition: lmstypes.h:64
ULONG MemoryTimer
Definition: lms2012.h:1482
void * pPool
Definition: c_memory.h:110
#define EXT_DATALOG
Rudolf datalog file.
Definition: lms2012.h:227
#define LFILE
Definition: lmstypes.h:39
void SetUiUpdate(void)
Definition: lms2012.c:396
#define snprintf
Definition: c_memory.c:75
char Buffer[1024]
Definition: c_wifi.c:102
void * cMemoryReallocate(PRGID PrgId, HANDLER Handle, GBINDEX Size)
Definition: c_memory.c:216
DATA8 Type
Definition: c_memory.h:112
#define DataF
void cMemorySortEntry(FOLDER *pMemory, UBYTE Type, char *pName)
Definition: c_memory.c:1588
void cMemoryFreeAll(void)
Definition: c_memory.c:364
PRGID CurrentProgramId(void)
Get current program id.
Definition: lms2012.c:207
void cMemoryFilename(PRGID PrgId, char *pName, char *pExt, DATA8 Length, char *pResult)
Definition: c_memory.c:1115
RESULT cMemoryGetItem(PRGID PrgId, HANDLER Handle, DATA16 Item, DATA8 Length, DATA8 *pName, DATA8 *pType)
Definition: c_memory.c:2023
void * VmMemoryResize(HANDLER Handle, DATA32 Elements)
Definition: lms2012.c:366
UWORD PRGID
Program id type.
Definition: lmstypes.h:71
#define POOL_TYPE_MEMORY
Definition: c_memory.h:105
RESULT cMemoryOpenFolder(PRGID PrgId, DATA8 Type, DATA8 *pFolderName, HANDLER *pHandle)
Definition: c_memory.c:1690
void cMemoryGetResourcePath(PRGID PrgId, char *pString, DATA8 MaxLength)
Definition: c_memory.c:1065
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
DATA8 FavouriteExts[FILETYPES]
Definition: c_memory.c:1570
DATA8 pArray[]
Definition: c_memory.h:125
RESULT cMemoryGetFolderItems(PRGID PrgId, HANDLER Handle, DATA16 *pItems)
Definition: c_memory.c:1742
#define EXT_GRAPHICS
Rudolf graphics file.
Definition: lms2012.h:224
MEMORY_GLOBALS * getMemoryInstance()
Definition: c_memory.c:86
DSPSTAT
Definition: lms2012.h:665
Object is stopped or not triggered yet.
Definition: bytecodes.h:1517
void Error(void)
opOUTPUT_READY byte code
Definition: lms2012.c:2839
GLOBALS VMInstance
Definition: lms2012.c:131
Break because of waiting for completion.
Definition: lms2012.h:671
#define MEMORY_FOLDER
Definition: lms2012.h:212
Dispatcher running (looping)
Definition: lms2012.h:667
DATA32 UsedElements
Definition: c_memory.h:120
DATA16 Entries
Definition: c_memory.c:1542
void cMemoryDeleteCacheFile(char *pFileName)
Definition: c_memory.c:687
DSPSTAT cMemoryReadFile(PRGID PrgId, HANDLER Handle, DATA32 Size, DATA8 Del, DATA8 *pDestination)
Definition: c_memory.c:1343
ULONG NewTime
Definition: lms2012.h:1464
#define NULL