Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpijs / script.cpp
1 /*****************************************************************************\
2   script.cpp : Implimentation for scripting
3
4   Copyright (c) 1996 - 2001, Hewlett-Packard Co.
5   All rights reserved.
6
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions
9   are met:
10   1. Redistributions of source code must retain the above copyright
11      notice, this list of conditions and the following disclaimer.
12   2. Redistributions in binary form must reproduce the above copyright
13      notice, this list of conditions and the following disclaimer in the
14      documentation and/or other materials provided with the distribution.
15   3. Neither the name of Hewlett-Packard nor the names of its
16      contributors may be used to endorse or promote products derived
17      from this software without specific prior written permission.
18
19   THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
22   NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24   TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
25   OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26   ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 \*****************************************************************************/
30
31 #if defined(APDK_CAPTURE)
32
33 #include "header.h"
34 #include "script.h"
35
36 APDK_BEGIN_NAMESPACE
37
38 extern char* Version(int bCompressed);
39
40 Scripter::Scripter(SystemServices* pSS):
41     pSys(pSS),
42     GlobalBuffer(NULL),
43     buffsize(0)
44 { }
45
46
47 Scripter::~Scripter()
48 { }
49
50
51 AsciiScripter::AsciiScripter(SystemServices* pSS)
52 : Scripter(pSS)
53 { }
54
55
56 AsciiScripter::~AsciiScripter()
57 { }
58
59
60 BinaryScripter::BinaryScripter(SystemServices* pSS)
61 : AsciiScripter(pSS)
62 { }
63
64
65 BinaryScripter::~BinaryScripter()
66 { }
67
68
69 DRIVER_ERROR SystemServices::InitScript(const char* FileName, BOOL ascii, BOOL read)
70 {
71     if (ascii)
72         pScripter = new AsciiScripter(this);
73     else pScripter = new BinaryScripter(this);
74
75     if (read)
76     {
77         replay=TRUE;
78         if (pScripter->OpenDebugStreamR(FileName))
79             return SYSTEM_ERROR;
80         else return NO_ERROR;
81     }
82     else
83     {
84         replay=FALSE;
85         if (pScripter->OpenDebugStreamW(FileName))
86                 return SYSTEM_ERROR;
87             else return NO_ERROR;
88     }
89
90 }
91
92 DRIVER_ERROR SystemServices::EndScript()
93 {
94     if (pScripter==NULL)
95         return SYSTEM_ERROR;
96
97     if (replay)
98     {
99         if (pScripter->CloseDebugStreamR())
100             return SYSTEM_ERROR;
101         else return NO_ERROR;
102     }
103     else
104     {
105         if (pScripter->CloseDebugStreamW())
106             return SYSTEM_ERROR;
107         else return NO_ERROR;
108     }
109
110     delete pScripter;
111 }
112
113
114 BOOL Scripter::ParseVer(char* str)
115 // set argProprietary
116 {
117 // example:
118 //"[platform-specific information]!!002.001_09-12-00 propscale openimg debug little_endian fonts:CTLU DJ400 DJ540 DJ600 DJ6xx DJ6xxPhoto DJ8xx DJ9xx Aladdin DJ630 eprinter"
119
120     char c;
121     char ver[5];
122     int i=0;
123     c=str[i];
124     while ((c!='!') && (c!=EOF))
125         c=str[++i];
126     if (c!='!')
127         return TRUE;
128     while ((c!=' ') && (c!=EOF))
129         c=str[++i];
130     if (c!=' ')
131         return TRUE;
132
133     for (int j=0; j<4; j++)
134         ver[j]=str[++i];
135     ver[4]='\0';
136
137     if (!strcmp(ver,"open"))            // old style
138         ;
139     else if (!strcmp(ver,"prop"))            // old style
140         ;
141     // new style
142     else
143     {
144         if (!strcmp(ver,"openscale"))
145             ;
146         else if (!strcmp(ver,"propscale"))
147             ;
148           else return TRUE;
149         if (!strcmp(ver,"openimg"))
150             ;
151         else if (!strcmp(ver,"propimg"))
152                 ;
153               else return TRUE;
154     }
155  return FALSE;
156 }
157
158 BOOL AsciiScripter::OpenDebugStreamR(const char* FileName)
159 {
160     int x;
161     char *str;
162
163     strncpy(ScriptFileName,FileName, sizeof(ScriptFileName)-1);
164
165     ScriptFile = fopen(ScriptFileName, "ra");
166
167     if (ScriptFile == NULL)
168         return TRUE;
169
170     char c=fgetc(ScriptFile);
171     fseek(ScriptFile,0, 0);
172
173     if (c==' ')             // spaces were never overwritten with tokencount
174     {
175         x = 2000;       // arbitrary guess
176
177     }
178     else if (GetDebugInt(x))
179             return TRUE;
180
181     TokenCount=x;
182     ReplayTokenCount=0;
183     fontcount=0;
184
185     if (GetDebugString(str,x))      // get $Version
186         return TRUE;
187
188     if (ParseVer(str))
189         return TRUE;
190
191   return FALSE;
192 }
193
194
195 BOOL AsciiScripter::CloseDebugStreamR()
196 {
197     if (GlobalBuffer != NULL)
198         pSys->FreeMem((BYTE*)GlobalBuffer,FALSE);
199
200     if (ScriptFile==NULL)
201         return TRUE;
202     return fclose(ScriptFile);
203 }
204
205
206 BOOL AsciiScripter::OpenDebugStreamW(const char* FileName)
207 {
208     strncpy(ScriptFileName,FileName, sizeof(ScriptFileName)-1);
209     ScriptFile = fopen(ScriptFileName, "wa");
210
211     if (ScriptFile == NULL)
212         return TRUE;
213
214     pSys->Capturing=TRUE;
215     TokenCount=0;
216     fontcount=0;
217
218     // set up debugging token strings
219     strcpy(TokString[0],"Job constructor");
220     strcpy(TokString[1],"Job destructor");
221     strcpy(TokString[2],"NewPage");
222     strcpy(TokString[3],"SendRasters");
223     strcpy(TokString[4],"TextOut");
224     strcpy(TokString[5],"UNUSED1");
225     strcpy(TokString[6],"Font destructor");
226     strcpy(TokString[7],"PrintContext constructor");
227     strcpy(TokString[8],"PrintContext destructor");
228     strcpy(TokString[9],"SetPixelsPerRow");
229     strcpy(TokString[10],"RealizeFont");
230     strcpy(TokString[11],"SelectDevice");
231     strcpy(TokString[12],"SelectPrintMode");
232     strcpy(TokString[13],"SetPaperSize");
233     strcpy(TokString[14],"UseBlackOnly");
234     strcpy(TokString[15],"UseColor");
235     strcpy(TokString[16],"SetInputResolution");
236     strcpy(TokString[17],"UNUSED");
237     strcpy(TokString[18],"UNUSED");
238     strcpy(TokString[19],"UNUSED");
239     strcpy(TokString[20],"String");
240     strcpy(TokString[21],"RLE stream");
241     strcpy(TokString[22],"RAW stream");
242     strcpy(TokString[23],"stream token");
243     strcpy(TokString[24],"NULL token");
244
245     for (int i=0; i<25; i++)
246         TokCount[i]=0;
247
248     fprintf(ScriptFile,"      ");
249
250     char version[TEMPLEN];
251     sprintf(version, Version(FALSE) );
252     int len = strlen(version);
253
254     if (PutDebugString(version, len))
255         return TRUE;
256
257
258     return FALSE;
259 }
260
261 BOOL AsciiScripter::CloseDebugStreamW()
262 {
263     if (ScriptFile==NULL)
264         return TRUE;
265
266     if (GlobalBuffer != NULL)
267         pSys->FreeMem((BYTE*)GlobalBuffer,FALSE);
268
269     fseek(ScriptFile,0, 0);
270     PutDebugInt(TokenCount);
271
272     pSys->Capturing=FALSE;
273
274
275     return fclose(ScriptFile);
276 }
277
278
279 BOOL AsciiScripter::PutDebugToken(const int token)
280 {
281     TokenCount++;
282     TokCount[token] =  TokCount[token]+1;
283
284     int res=fprintf(ScriptFile,"%%%0x ",token);
285     if (res<1)
286         return TRUE;
287
288     res=fprintf(ScriptFile,"\n%s:%d\n",TokString[token], TokCount[token]);
289
290     return (res < 1);   // bad if res<1
291 }
292
293
294 BOOL AsciiScripter::PutDebugInt(const int data)
295 {
296     int res=fprintf(ScriptFile,"%%%0x ",data);
297   return (res < 1);   // bad if res<1
298 }
299
300
301 BOOL AsciiScripter::PutDebugByte(const BYTE data)
302 { return PutDebugInt(data); }
303
304
305 BOOL AsciiScripter::PutDebugString(const char* str,const int len)
306 {
307    if (PutDebugToken(tokCharPtr))
308        return TRUE;
309    if (PutDebugInt(len))
310        return TRUE;
311
312    fputc('"',ScriptFile);
313    for (int i=0; i < len; i++)
314         fprintf(ScriptFile,"%c",str[i]);
315    fputc('"',ScriptFile);
316
317 return FALSE;
318 }
319
320
321 BOOL AsciiScripter::PutDebugStream(const BYTE* str,const int len)
322 {
323 // Does modified run-length-encoding from stream.
324 // len=length of raw stream
325     int total=1; short count,i,j; BYTE current,next,last;
326     BOOL rle=TRUE;
327     short chunkarray[3];
328
329     if ((len==0) || (str==NULL))
330     {
331         PutDebugToken(tokRawStream);
332         fprintf(ScriptFile,"%%%0x ", len);
333         return FALSE;
334     }
335
336     next=0; // suppress stupid compiler warning
337     int alloclen= len*2;        // in worst case each byte produces [count=1][byte]
338     if (buffsize < alloclen)
339       {
340         if (GlobalBuffer!=NULL)
341             pSys->FreeMem((BYTE*)GlobalBuffer,FALSE);
342         GlobalBuffer = (short*)pSys->AllocMem(alloclen,FALSE);
343         buffsize=alloclen;
344       }
345
346     short* buff = GlobalBuffer;
347
348     short *thebuff=buff;
349         if (buff==NULL)
350             return TRUE;
351     const BYTE *startstream=str;
352
353     for (i=0;i<3;i++)   // go through 3 times, for r,g,b
354     {
355         short* startbuff=buff;
356         const BYTE* stream=startstream+i;
357         total=1;
358         current = *stream; stream+=3;
359         while (total<(len/3))
360         {
361             count=1;
362             while ((total<(len/3)) && (current == (next= *stream)) )
363                 { count++; total++; stream+=3; }
364             if (total<(len/3))
365                 { next= *stream; stream+=3; total++; }
366             buff[0]=count; buff[1]=current;
367             buff+=2;
368             last=current;
369             current=next;
370         }
371         // get last item if it is a single
372         if (current != last)
373           {
374             buff[0]=count; buff[1]=current;
375             buff+=2;
376           }
377
378         int chunks=(buff-startbuff)/2;
379         if (chunks>(len/6))
380         { rle=FALSE; break; }
381         else chunkarray[i]=chunks;
382     }
383
384     if (!rle)
385     {
386         PutDebugToken(tokRawStream);
387         fprintf(ScriptFile,"%%%0x ", len);
388         for (i=0;i<len;i++)
389             fprintf(ScriptFile,"%%%0x ",startstream[i]);
390
391     }
392     else
393     { total=0;
394       PutDebugToken(tokRLEstream);
395       fprintf(ScriptFile,"%%%0x ",len);
396       for (i=0;i<3;i++)
397         { count=chunkarray[i];
398             for (j=0;j<count;j++)
399                 fprintf(ScriptFile,"%%%0x %%%0x ",thebuff[total+2*j],thebuff[total+2*j+1]);
400           total += count*2;
401         }
402     }
403
404 return FALSE;
405 }
406
407
408 ///////////////////////////////////////////////////////////////////
409 BOOL AsciiScripter::FindPercent()
410 // find our token '%'
411 // return TRUE iff EOF
412 {
413     char c;
414     c=fgetc(ScriptFile);
415     while ((c!='%') && (c!=EOF))
416     {
417         c=fgetc(ScriptFile);
418     }
419     return (c==EOF);
420 }
421
422
423 char* AsciiScripter::digits()
424 // includes filtering of CR/LF's
425 {
426     char c;
427     char *str=scanner;
428     BOOL done=FALSE;
429
430     while (!done)
431     {
432         c=fgetc(ScriptFile);
433         if (((c>='0')&&(c<='9')) ||
434             ((c>='a')&&(c<='f')) ||
435             ((c>='A')&&(c<='F'))
436            )
437             *str++ = c;
438         else if (c==' ')
439                 { done=TRUE; *str++=c; }
440              else if ((c!=10)&&(c!=13))
441                 { scanner[0]=0; done=TRUE; }
442     }
443     *str=0;
444     return scanner;
445 }
446
447
448
449 void AsciiScripter::ReadRLE(int instreamlen, BYTE* outstream)
450 // Does run-length-decoding from stream.
451 {
452     int count,total,i,j;
453     BYTE b;
454     int bi;
455     BYTE* buff=(BYTE*)pSys->AllocMem(instreamlen*2,FALSE);
456     int colorsize=instreamlen/3;
457
458     // first fill up 3-part buffer with all reds,then all greens, all blues
459
460     for (i=0;i<3;i++)   // for each color
461       { total=0;
462           while (total<colorsize)
463           // assumes correct input, so that total count=instreamlen/3
464           {
465             if (FindPercent())
466                 break;
467             sscanf(digits(),"%x ",&count);
468             if (FindPercent())
469                 break;
470             sscanf(digits(),"%x ",&bi);
471             b= (BYTE)bi;
472             for (j=0;j<count;j++)
473                    buff[ total + (i*colorsize) + j ] = b;
474             total+=count;
475           }
476       }
477
478     // now interleave
479
480     for (i=0;i<(instreamlen/3);i++)
481       {
482         *outstream++ = buff[i];
483         *outstream++ = buff[i+colorsize];
484         *outstream++ = buff[i+(2*colorsize)];
485       }
486     pSys->FreeMem(buff,FALSE);
487 }
488
489
490 void AsciiScripter::ReadRaw(int instreamlen, BYTE* outstream)
491 {
492     BYTE b; int bi;
493     for (int i=0;i<instreamlen;i++)
494       { if (FindPercent())
495             break;
496         sscanf(digits(),"%x ",&bi);
497         b=(BYTE)bi;
498         *outstream++ = b; }
499 }
500
501
502 ///////////////////////////////////////////////////////////////////
503 BOOL AsciiScripter::GetDebugToken(int& token)
504 {
505     char c;
506
507     if (GetDebugInt(token))
508         return TRUE;
509     if ((token<0)||(token>LAST_TOKEN))
510         return TRUE;
511
512     // now expect LF<string>LF
513     c=fgetc(ScriptFile);
514     if (c!=10)
515         return TRUE;
516
517     while ( (c=fgetc(ScriptFile))!=10) ;
518     // successfully ate debug string
519
520     ReplayTokenCount++;
521
522  return FALSE;
523 }
524
525
526 BOOL AsciiScripter::GetDebugInt(int& data)
527 { int res,k;
528
529     if (FindPercent())
530       { data=-1; return TRUE; }
531
532     res = sscanf(digits(),"%x ",&k);
533     if (!res)
534         data = -1;
535     else data=k;
536  return FALSE;
537 }
538
539
540 BOOL AsciiScripter::GetDebugByte(BYTE& data)
541 {
542     int temp;
543     BOOL res=GetDebugInt(temp);
544     if (res)
545         return TRUE;
546     data=temp;
547     return FALSE;
548 }
549
550
551 BOOL AsciiScripter::GetDebugString(char*& str,int& length)
552 {
553     int res,len,i;
554     str=NULL;   // in case of err rtn
555
556     for (i=0; i<TEMPLEN; i++)
557         tempStr[i]=0;
558
559     GetDebugInt(res);   // look for tokCharPtr
560     if (res != tokCharPtr)
561         return TRUE;
562     GetDebugInt(len);   // get length
563
564     if (len >= TEMPLEN)
565         return TRUE;
566
567     char c=fgetc(ScriptFile);
568     if (c!='"')
569         return TRUE;
570     i=0;
571     tempStr[i]=fgetc(ScriptFile);
572     while ((i<TEMPLEN) && (tempStr[i] != '"'))
573         tempStr[++i]=fgetc(ScriptFile);
574
575     if ((i==TEMPLEN) || (i!=len))
576         return TRUE;
577
578     tempStr[i]=0;
579     str=tempStr;
580     length=len;
581
582     return FALSE;
583 }
584
585
586 BOOL AsciiScripter::GetDebugStream(const unsigned int buffersize, BYTE*& buffer)
587 {
588     BYTE tok;
589     int token;
590
591     GetDebugToken(token);
592     if (token == tokStream)
593     {
594         buffer = (BYTE*)pSys->AllocMem(buffersize,FALSE);
595         if (buffer==NULL)
596             return TRUE;
597         int len;
598
599         GetDebugInt(len);
600         if (len==0)
601             return FALSE;
602         if (((unsigned int)len) != buffersize)
603             return TRUE;
604
605         for (int i=0; i < len; i++)
606         {
607             GetDebugByte(tok);
608             buffer[i] = tok;
609         }
610     }
611     else if ((token == tokRLEstream) || (token == tokRawStream))
612           {
613             int len;
614
615             GetDebugInt(len);
616             if (len==0)
617                 buffer=NULL;
618             else
619             {
620                 buffer = (BYTE*)pSys->AllocMem(len,FALSE);
621                 if (token == tokRLEstream)
622                     ReadRLE(len, buffer);
623                 else ReadRaw(len, buffer);
624             }
625           }
626         else return TRUE;
627
628  return FALSE;
629 }
630
631
632 /////////////////////////////////////////////////////////////////////
633 BOOL BinaryScripter::OpenDebugStreamR(const char* FileName)
634 {
635     strncpy(ScriptFileName,FileName, sizeof(ScriptFileName)-1);
636
637     ScriptFile = fopen(ScriptFileName, "rb");
638
639     if (ScriptFile == NULL)
640         return TRUE;
641
642     int x;
643     if (GetDebugInt(x))
644         return TRUE;
645     TokenCount=x;
646     ReplayTokenCount=0;
647     fontcount=0;
648
649     char *ver;
650     if (GetDebugString(ver,x))
651         return TRUE;
652
653     if (ParseVer(ver))
654         return TRUE;
655
656   return FALSE;
657 }
658
659
660 BOOL BinaryScripter::OpenDebugStreamW(const char* FileName)
661 {
662     strncpy(ScriptFileName,FileName, sizeof(ScriptFileName)-1);
663     ScriptFile = fopen(ScriptFileName, "wb");
664
665     if (ScriptFile == NULL)
666         return TRUE;
667
668     pSys->Capturing=TRUE;
669     TokenCount=0;
670     fontcount=0;
671
672     PutDebugInt(-1);  // leave space for token count
673
674     char version[TEMPLEN];
675     sprintf(version, Version(FALSE) );
676     int len = strlen(version);
677
678     if (PutDebugString(version, len))
679         return TRUE;
680
681     return FALSE;
682 }
683
684 BOOL BinaryScripter::PutDebugToken(const int token)
685 {
686     TokenCount++;
687
688    return PutDebugByte(token);
689 }
690
691
692 BOOL BinaryScripter::PutDebugInt(const int data)
693 {
694     int res=fwrite( &data, sizeof(int), 1, ScriptFile );
695   return (res == EOF);
696 }
697
698
699 BOOL BinaryScripter::PutDebugByte(const BYTE data)
700 {
701     int res=fputc( data, ScriptFile );
702   return (res == EOF);
703 }
704
705
706 BOOL BinaryScripter::PutDebugString(const char* str,const int len)
707 {
708    if (PutDebugToken(tokCharPtr))
709        return TRUE;
710    if (PutDebugInt(len))
711        return TRUE;
712
713    for (int i=0; i < len; i++)
714         if ((fputc(str[i],ScriptFile))==EOF)
715             return TRUE;
716
717 return FALSE;
718 }
719
720 BOOL BinaryScripter::PutDebugStream(const BYTE* str,const int len)
721 {
722    if (PutDebugToken(tokStream))
723        return TRUE;
724    if (PutDebugInt(len))
725        return TRUE;
726
727    for (int i=0; i < len; i++)
728         if ((fputc(str[i],ScriptFile))==EOF)
729             return TRUE;
730
731 return FALSE;
732 }
733
734
735 BOOL BinaryScripter::GetDebugToken(int& token)
736 {
737     BYTE b;
738     if (GetDebugByte(b))
739         return TRUE;
740     token=b;
741     if (token>LAST_TOKEN)
742         return TRUE;
743
744     ReplayTokenCount++;
745
746  return FALSE;
747 }
748
749
750 BOOL BinaryScripter::GetDebugInt(int& data)
751 {
752     int temp;
753     int res = fread(&temp, sizeof(int), 1, ScriptFile);
754     data=temp;
755     return (res<1);
756 }
757
758
759 BOOL BinaryScripter::GetDebugByte(BYTE& data)
760 {
761     data=fgetc(ScriptFile);
762  return FALSE;
763 }
764
765
766 BOOL BinaryScripter::GetDebugString(char*& str,int& length)
767 {
768     int res,len,i;
769     str=NULL;   // in case of err rtn
770
771     for (i=0; i<TEMPLEN; i++)
772         tempStr[i]=0;
773
774     GetDebugToken(res); // look for tokCharPtr
775     if (res != tokCharPtr)
776         return TRUE;
777     GetDebugInt(len);   // get length
778
779     if (len >= TEMPLEN)
780         return TRUE;
781
782     for (i=0; i<len; i++)
783         if ((tempStr[i]=fgetc(ScriptFile))==EOF)
784             return TRUE;
785
786     tempStr[i]=0;
787     str=tempStr;
788     length=len;
789
790     return FALSE;
791 }
792
793
794 BOOL BinaryScripter::GetDebugStream(const unsigned int buffersize, BYTE*& buffer)
795 {
796     int token;
797     BYTE tok;
798
799     GetDebugToken(token);
800     if (token != tokStream)
801         return TRUE;
802
803     buffer = (BYTE*)pSys->AllocMem(buffersize,FALSE);
804     if (buffer==NULL)
805         return TRUE;
806     int len;
807
808     GetDebugInt(len);
809     if (len==0)
810     {
811         pSys->FreeMem(buffer,FALSE);
812         buffer=NULL;
813         return FALSE;
814     }
815     if (((unsigned int)len) != buffersize)
816         return TRUE;
817
818     for (int i=0; i < len; i++)
819     {
820         GetDebugByte(tok);
821         buffer[i] = tok;
822     }
823
824     return FALSE;
825 }
826
827 APDK_END_NAMESPACE
828
829 #endif //APDK_CAPTURE
830