1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
/*
Copyright 1990-2008 Light Infocon Tecnologia S/A
Este arquivo é parte do programa LightBase - Banco de Dados Textual Documental
O LightBase é um software livre; você pode redistribui-lo e/ou modifica-lo dentro
dos termos da Licença Pública Geral GNU como publicada pela Fundação do Software
Livre (FSF); na versão 2 da Licença.
Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA
GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou APLICAÇÃO
EM PARTICULAR. Veja a Licença Pública Geral GNU para maiores detalhes.
Você deve ter recebido uma cópia da Licença Pública Geral GNU versao 2, sob o
título "LICENCA.txt", junto com este programa, se não, escreva para a Fundação do
Software Livre(FSF) Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//
// void * ALStorage::operator new( size_t size )
//
// ARGUMENTS:
//
// size : The number of bytes needed to create a new ALStorage object.
//
// RETURNS
//
// A pointer to the newly allocated storage area, or 0 if no storage
// was available.
//
// DESCRIPTION
//
// When using a DLL, it is easy to get into a dangerous situation when
// creating objects whose ctor and dtor are both in the DLL. The problem
// arises because when you create an object using new, the memory for
// the object will be allocated from the EXE. However, when you destroy
// the object using delete, the memory is freed inside the DLL. Since
// the DLL doesn't really own that memory, bad things can happen.
//
// But, you say, won't the space just go back to the Windows heap regardless
// of who tries to free it? Maybe, but maybe not. If the DLL is using
// a subsegment allocation scheme, it might do some sort of local free
// before returning the space to the windows heap. That is the point where
// you could conceivably cook your heap.
//
// By providing our own version of operator new inside this class, we
// ensure that all memory allocation for the class will be done from
// inside the DLL, not the EXE calling the DLL.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
void AL_DLL_FAR * AL_PROTO ALStorage::operator new
//
// ALStorage::ALStorage( const char *file_name,
// size_t size,
// const enum ALStorageType object_type,
// ALCase name_case )
//
// ARGUMENTS:
//
// file_name : The name to assign to the mName data member of the
// newly created storage object.
//
// size : The size of the I/O buffer that is going to be used
// for the storage object. ALFile uses 4096 as a default.
//
// object_type : The type of object, as defined in ALDEFS.H. Good
// values include AL_FILE_OBJECT and AL_MEMORY_OBJECT.
//
// name_case : The case sensitivity of the object name. For objects
// such as ALFile, AL_MIXED is a no-no. Those objects
// need to be forced to convert names to all upper
// or all lower, because the operating system considers
// file names to be case insensitive.
//
// RETURNS
//
// Nothing, it is a constructor.
//
// DESCRIPTION
//
// The constructor for ALStorage gets called from the constructor of
// derived classes. It has to initialize all sorts of data members.
// First, in the initializer list, it sets up the mName data member,
// as well as muBufferSize and miStorageObjectType. The latter two
// data members are set to be const so I can make them public, which
// means we have to initialize them in the initializer list.
//
// In the body of the constructor, we initialize a bunch of data members,
// none of which mean anything at this point.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
AL_PROTO : mName,
,
//
// ALStorage::~ALStorage()
//
// ARGUMENTS:
//
// No arguments for destructors.
//
// RETURNS
//
// No returns from destructors.
//
// DESCRIPTION
//
// In debug mode, we first check to make sure we are destroying the
// right type of object.
//
// The only thing left to do is free up the I/O buffer if it is still
// allocated. This piece of work probably isn't necessary. Since this
// is a virtual destructor, we will be called after the destructors
// for the derived class. Any derived class that is doing its job
// will make sure that it calls Close() before destroying itself. If
// it doesn't, it will probably be leaving unfinished business behind
// that we aren't going to be able to deal with here. Even so, we will
// be diligent in our attention to detail.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
AL_PROTO ALStorage::~
//
// This giant table is used by the CRC routines. These are the coefficients
// for calculating the CCITT 32 bit CRC. I typed these in from memory, so
// I hope they are correct.
//
static unsigned long ccitt_32 =
;
//
// void ALStorage::UpdateCrc( size_t count )
//
// ARGUMENTS:
//
// count : The number of characters to process in the I/O buffer.
//
// RETURNS
//
// Nothing.
//
// DESCRIPTION
//
// If CRC checking has been turned on for the storage object, this
// routine will be called every time LoadBuffer() or FlushBuffer()
// are called. It does CRC checking on a buffer full of data at
// a time. Hopefully this means the compiler can optimize the
// heck out of this code.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
void AL_PROTO
//
// int ALStorage::Open()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// AL_SUCCESS, or AL_CANT_OPEN_BUFFER on memory allocation failure.
// If the object was already in an error state, it is very possible to
// get some other error code < 0.
//
// DESCRIPTION
//
// Any derived class needs to have its own Open() function. However,
// the derived class can also call this Open() function in the base
// class to do some odds and ends for it. The most important thing it
// does is allocate the I/O buffer, which is what makes ALStorage a
// relatively fast way to read and write data. Although the buffer
// is in place, there is no data in it, so this guy also sets up the
// indices and pointers to reflect that.
//
// Upon exit, all you need to to is start reading or writing, and the
// whole thing should be ready to go.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::Create()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// AL_SUCCESS, or AL_CANT_OPEN_BUFFER on memory allocation failure.
// If the object was already in an error state, it is very possible to
// get some other error code < 0.
//
// DESCRIPTION
//
// This function is nearly identical to ALStorage::Open().
//
// Any derived class needs to have its own Create() function. However,
// the derived class can also call this Create() function in the base
// class to do some odds and ends for it. The most important thing it
// does is allocate the I/O buffer, which is what makes ALStorage a
// relatively fast way to read and write data. Although the buffer
// is in place, there is no data in it, so this guy also sets up the
// indices and pointers to reflect that.
//
// Upon exit, all you need to to is start writing, and the
// whole thing should be ready to go.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
// July 7, 1994 1.0B : When I create a file now, I set mlSize to 0. I was
// running into trouble when I reused ALMemory objects.
// After creating them and closing them, mlSize was
// non-zero. If I went back and created the file
// again, I would keep the old mlSize, which was still
// non-zero. Doesn't make sense for newly created
// file.
//
int AL_PROTO
//
// int ALStorage::Close()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// The current integer status of the object. Hopefully this will be
// AL_SUCCESS, but it could well be a value < AL_SUCCESS.
//
// DESCRIPTION
//
// Just like with Open(), must derived classes will have their own
// versions of Close(). They can call this version to delete the I/O
// buffer if they feel like it is too hard to do themselves.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// long ALStorage::GetCrc32()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// The current value of the CRC-32.
//
// DESCRIPTION
//
// This function is used to get the CRC-32 of a storage object. But it
// does a little bit more than just give you the CRC. First, it makes
// sure the buffers have been flushed, so that the CRC is accurate. If
// we didn't do this we might try to get the CRC on an incompletely
// written file.
//
// Once we get the CRC,the miUpdateCrcFlag is set to 0, which means
// that from here on out the value will not be updated. So retrieving
// the CRC means you are no longer interested in further calculation.
// It also means you can trust the value you just read, because it
// will never be modified again.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
long AL_PROTO
//
// void ALStorage::InitCrc32( unsigned long seed = 0xffffffffL )
//
// ARGUMENTS:
//
// seed : The long value to start the CRC off at. There is probably
// no reason to change this from the default value, although
// I won't be surprised if someone comes up with one.
//
// RETURNS
//
// Nothing.
//
// DESCRIPTION
//
// Calling this function kicks off the CRC calculation for a given
// storage object should be done immediately after the object is
// opened. Once the miUpdateCrcFlag is set, the CRC will be updated
// every time a LoadBuffer() or FlushBuffer() is called.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
void AL_PROTO
//
// size_t ALStorage::ReadBuffer( unsigned char *buf, size_t length )
//
// ARGUMENTS:
//
// buf : The buffer that is going to receive input characters.
//
// length : The number of bytes you want to read.
//
// RETURNS
//
// The number of bytes read in, always. If this function generates an
// error, it will be found in the mStatus member.
//
// DESCRIPTION
//
// We could write a simple version of this function by just calling
// ReadChar() over and over, but it would be nice to do things
// a little more efficiently. Since we have this nice big buffer
// full of data ready to read, it makes sense to copy big chunks of
// it in one fell swoop. That is what this guy does. It sits in a loop
// doing a memcpy() followed by LoadBuffer() until all of the data
// that has been asked for got moved. As data is read in, we have to
// update the data member muReadIndex. Other data members will get
// updated by LoadBuffer().
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
size_t AL_PROTO
//
// size_t ALStorage::WriteBuffer( const unsigned char *buf,
// size_t length )
//
// ARGUMENTS:
//
// buf : The buffer that is contains the output data.
//
// length : The number of bytes you want to write.
//
// RETURNS
//
// The number of bytes written, always. If this function generates an
// error, it will be found in the mStatus member.
//
// DESCRIPTION
//
// We could write a simple version of this function by just calling
// WriteChar() over and over, but it would be nice to do things
// a little more efficiently. Since we have this nice big buffer
// just waiting for data, it makes sense to copy big chunks to
// it in one fell swoop. That is what this guy does. It sits in a loop
// doing a memcpy() followed by FlushBuffer() until all of the data
// that was ready to go has been sent. As data is written, we have to
// update the data member muWriteIndex. Other data members will get
// updated by FlushBuffer().
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
size_t AL_PROTO
//
// int ALStorage::WritePortableShort( short int short_data )
//
// ARGUMENTS:
//
// short_data : A 16 bit int that is going to be written out in
// little endian format.
//
// RETURNS
//
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
//
// DESCRIPTION
//
// In order to make sure our archives can be read and written on all sorts
// of systems, we have a few functions that are used to write numerical
// data in a portable fashion. This function writes short integers in
// little endian format (which is not native Intel format). The complementary
// function, ReadPortableShort(), reads short integers back using the
// same format.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::WritePortableLong( long int long_data )
//
// ARGUMENTS:
//
// long_data : A 32 bit long int that is going to be written out in
// little endian format.
//
// RETURNS
//
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
//
// DESCRIPTION
//
// In order to make sure our archives can be read and written on all sorts
// of systems, we have a few functions that are used to write numerical
// data in a portable fashion. This function writes long integers in
// little endian format (which is not native Intel format). The
// complementary function, ReadPortableLong(), reads long integers back
// using the same format.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::ReadPortableShort( short int &short_data )
//
// ARGUMENTS:
//
// short_data : A reference to a 16 bit integer that is going to
// have data read in from this storage object.
//
// RETURNS
//
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
//
// DESCRIPTION
//
// In order to make sure our archives can be read and written on all sorts
// of systems, we have a few functions that are used to read numerical
// data in a portable fashion. This function reads short integers in
// little endian format (which is not native Intel format). The
// complementary function, WritePortableShort(), writes short integers out
// using the same format.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::ReadPortableLong( long int &short_data )
//
// ARGUMENTS:
//
// long_data : A reference to a 32 bit integer that is going to
// have data read in from this storage object.
//
// RETURNS
//
// AL_SUCCESS if all goes well. Otherwise, some error code < AL_STATUS.
//
// DESCRIPTION
//
// In order to make sure our archives can be read and written on all sorts
// of systems, we have a few functions that are used to read numerical
// data in a portable fashion. This function reads long integers in
// little endian format (which is not native Intel format). The
// complementary function, WritePortableLong(), writes long integers out
// using the same format.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::WriteString( const char *string_data )
//
// ARGUMENTS:
//
// string_data : A string to be written out in our portable format.
//
// RETURNS
//
// AL_SUCCESS if things work, or an error code < AL_SUCCESS if an error
// occurs writing the data out.
//
// DESCRIPTION
//
// We write random length data to archive directories using this special
// format, which is a 16 bit int describing the length of the data,
// followed by the data itself. All of the storage objects and compression
// engines write their own private data out using this format. This
// means that even if another class doesn't understand the content of data
// stored in this format, at least it knows how to read it in so as to
// move past it.
//
// This function won't write just any random data, it is specifically
// oriented towards C strings. This means it is mostly used to write
// file names and comments. Their are a few places where classes
// write private data that isn't kept in C strings, they just manually
// write the length with WritePortableShort(), followed by the data.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
// PROTECTED MEMBER FUNCTION
//
// char * ALStorage::ReadString()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// A pointer to a string. This string has been allocated by the library,
// which can cause a problem if you are using a DLL. If an EXE tried
// to free a string pointer allocated by the DLL, havoc would result.
// Because of this hassle, this is a protected function.
//
// The solution to this is to write a new version of this that returns
// an ALName object. I thought of that, but too late.
//
// DESCRIPTION
//
// This function is used internally by ArchiveLib. It is used to read
// random length blocks of data out of archives (or other storage objects).
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
char AL_DLL_FAR * AL_PROTO
//
// long ALStorage::Tell()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// A long integer indicating the current position of the read/write
// pointer for the file.
//
// DESCRIPTION
//
// Because we are using buffered I/O here, figuring out the current
// position of the read write pointer is just a tiny bit more complicated
// than just checking a pointer. We have to find the physical location of
// the file pointer, then add in any offset created by the presence of
// data in the I/O buffer.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
long AL_PROTO
//
// void ALStorage::YieldTime()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// Nothing.
//
// DESCRIPTION
//
// This function has two important things to do. It gets called
// at a few different points in the process of reading or writing data
// from storage objects. During normal reading and writing, it
// will get called every time the buffer is loaded or flushed.
//
// If we are in Windows mode, we execute a PeekMessage() loop. This
// makes sure that we aren't hogging the CPU. By doing it this way,
// the programmer can be ensure that he/she is being a good citizen
// without any significant effort.
//
// The second important function is that of calling the monitor function.
// The user interface elements need to be updated regularly, and this
// is done via this call.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
void AL_PROTO
//
// int ALStorage::WriteStorageObjectData( ALStorage * archive )
//
// ARGUMENTS:
//
// archive : A pointer to the storage object where we are going to
// write the private data.
//
// RETURNS
//
// AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
//
// DESCRIPTION
//
// All storage objects have the ability to create a private data block
// that will be stored along with the directory when creating an archive.
// None of the classes predefined in ArchiveLib use this data block, which
// means they use this function instead of providing their own virtual
// substitute. This function writes a private data block of exactly 0
// bytes in length. Our internal storage format means that a block
// of 0 bytes length takes 2 bytes to store.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// int ALStorage::ReadStorageObjectData( ALStorage * archive )
//
// ARGUMENTS:
//
// archive : A pointer to the storage object where we are going to
// read in the private data..
//
// RETURNS
//
// AL_SUCCESS if things went okay, otherwise an error code < AL_SUCCESS.
//
// DESCRIPTION
//
// All storage objects have the ability to create a private data block
// that will be stored along with the directory when creating an archive.
// None of the classes predefined in ArchiveLib use this data block, which
// means they use this function instead of providing their own virtual
// substitute. This function reads a private data block of exactly 0
// bytes in length. Our internal storage format means that a block
// of 0 bytes length takes 2 bytes to store.
//
// In debug mode, we get really bent out of shape if this data block
// doesn't look exactly like we expect it to.
//
// REVISION HISTORY
//
// May 26, 1994 1.0A : First release
//
int AL_PROTO
//
// char * ALStorage::ReadCopyright()
//
// ARGUMENTS:
//
// None.
//
// RETURNS
//
// A pointer to a copyright notice.
//
// DESCRIPTION
//
// It is a good idea for us to have a copyright notice embedded in the
// library. Hopefully, this notice will show up in any executables linked
// using this library, or in the DLL they link to.
//
// REVISION HISTORY
//
// August 10, 1994