OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
file.cpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1993, 1996 by Borland International, All Rights Reserved
4// Copyright (c) 1996-1998 Bidus Yura, All rights Reserved
5//
6/// \file
7/// TFile class implementation.
8/// Fully rewritten by Yura Bidus
9//------------------------------------------------------------------------------
10#include <owl/pch.h>
11#include <owl/file.h>
12#include <owl/wsyscls.h>
13
14#if defined(OWL5_COMPAT) // See TFile::GetStatus.
15#include <owl/filename.h>
16#endif
17
18#if defined(__BORLANDC__)
19# pragma option -w-ccc // Disable warning; "Condition is always true/false".
20# pragma option -w-inl // Disable warning in standard library; "Functions containing 'statement' are not expanded inline".
21#endif
22
23using namespace std;
24
25namespace owl {
26
28
29/// \cond
30
31// ////////////////////////////
32// Internal support structure
33#include <pshpack1.h>
34struct __i_uint32_32{
35 uint32 Lo;
36 uint32 Hi;
37};
38struct __i_int32_32{
39 uint32 Lo;
40 int32 Hi;
41};
42#include <poppack.h>
43
44/// \endcond
45
46
48
49//
50/// Constructs an exception handling class with identity IDS_BADFILEFORMAT.
51//
57
58//
59/// Construct a TXBadFormat exception from scratch, and throws it.
60//
61void
63{
64 TXBadFormat().Throw();
65}
66
67
70{
71 return new TXBadFormat(*this);
72}
73
74
75//
76//
77void
79{
80 throw *this;
81}
82
83//------------------------------------------------------------------------------
84////////////////////////////////////////////////////////////////////////////////
85//
86// class TDiskFileHandle
87// ~~~~~ ~~~~~~~~~~~~~~~
88//
89//
90// helper functions
91static void sys2Mode(uint32& access, uint32& sharedMode, uint32& howOpen, uint32 openMode)
92{
97
99 sharedMode |= 0; // exclisive - default
104
105// if(openMode & TFile::PermNone) // not implemented in WIN32
106// ShareMode |= 0; //
107
109 howOpen |= CREATE_NEW ; // open
111 howOpen |= CREATE_ALWAYS; // open
113 howOpen |= OPEN_EXISTING; // open
115 howOpen |= TRUNCATE_EXISTING; // open
116}
117
118//
119// class TDiskFileHandle
120// ~~~~ ~~~~~~~~~~~~~~~
121//
123{
124 OpenMode = mode;
126
127 uint32 Access = 0;
128 uint32 ShareMode = 0;
129 uint32 HowOpen = 0;
130 sys2Mode(Access, ShareMode, HowOpen, OpenMode);
131
133 Handle = ::CreateFile(FileName.c_str(),Access,ShareMode,nullptr,HowOpen,flags,nullptr);
134}
135
136
137//
139:
140 Handle(handle), OpenMode(mode), FileName(fileName)
141{
142}
143
144
145//
148{
149 HANDLE hHandle = 0;
152 0, false, DUPLICATE_SAME_ACCESS) && hHandle)
153 return new TDiskFileHandle(hHandle, FileName.c_str(), OpenMode);
154 return nullptr;
155}
156
157
158//
160{
161 return ::GetLastError();
162}
163
164
165//
167{
169 return false;
170 return true;
171}
172
173
174//
176{
178 if(::ReadFile(Handle, buffer, numBytes, &u32Ret, nullptr))
179 return u32Ret;
180 return TFILE_ERROR;
181}
182
183
184//
186{
188 if(::WriteFile(Handle, buffer, numBytes, &u32ret, nullptr))
189 return true;
190 return false;
191}
192
193
194//
196{
198 return false;
200 return true;
201 return false;
202}
203
204
205//
207{
208 uint32 ret = ::SetFilePointer(Handle,0,nullptr,static_cast<uint32>(TFile::cur));
209 return uint64(ret);
210}
211
212
213//
215{
217 ul.Lo = ::GetFileSize(Handle, reinterpret_cast<DWORD *>(&ul.Hi));
218 return *reinterpret_cast<uint64*>(&ul);
219}
220
221
222//
224{
225 if(Seek(static_cast<long>(newLen), TFile::beg) == TFILE_ERROR)
226 return false;
228 return true;
229 return false;
230}
231
232
233//
235{
236 uint32 ret = ::SetFilePointer(Handle,0,nullptr,static_cast<uint32>(TFile::cur));
237 if( ret != 0xFFFFFFFF)
238 return ret;
239 return TFILE_ERROR;
240}
241
242
243//
245{
246 uint32 ret = ::GetFileSize(Handle, nullptr);
247 if( ret != 0xFFFFFFFF)
248 return ret;
249 return TFILE_ERROR;
250}
251
252
254{
255 __i_int32_32 ul = *reinterpret_cast<__i_int32_32*>(&offset);
256 ul.Lo = ::SetFilePointer(Handle,ul.Lo,reinterpret_cast<LONG*>(&ul.Hi),static_cast<uint32>(origin));
257 return uint64(*reinterpret_cast<int64*>(&ul));
258}
259
260//
262{
263 uint32 ret = ::SetFilePointer(Handle,offset,nullptr,static_cast<uint32>(origin));
264 if( ret != 0xFFFFFFFF)
265 return ret;
266 return TFILE_ERROR;
267}
268
269
270//
272{
274 return true;
275 return false;
276}
277
278//
280{
281 return ::LockFile(Handle,position,0, count,0);
282}
283
284//
286{
287 if(::UnlockFile(Handle,position, 0, count, 0))
288 return true;
289 return false;
290}
291
292
294{
295 __i_uint32_32 up = *reinterpret_cast<__i_uint32_32*>(&position);
296 __i_uint32_32 uc = *reinterpret_cast<__i_uint32_32*>(&count);
297 return ::LockFile(Handle, up.Lo,up.Hi,uc.Lo,uc.Hi);
298}
299//
301{
302 __i_uint32_32 up = *reinterpret_cast<__i_uint32_32*>(&position);
303 __i_uint32_32 uc = *reinterpret_cast<__i_uint32_32*>(&count);
304 return ::UnlockFile(Handle, up.Lo,up.Hi, uc.Lo,uc.Hi);
305}
306
307
308///////////////////////////////////////////////////////////////////////////
309//--------------------------------------------------------------
310//------------------------------------------------------------------------------
311
351
352
357
358//
360{
361 if (::_tfullpath(status.fullName, FileName.c_str(), COUNTOF(status.fullName)) == nullptr){
362 status.fullName[0] = 0;
363 return false;
364 }
366 if(attrib == TFILE_ERROR)
367 return false;
368
369 status.attribute = __sys2Atr(attrib);
370
372 if(::GetFileTime(Handle, &ftCreate, &ftAccess, &ftWrite) == FALSE)
373 return false;
374
375 //uint16 ftime,fdate;
376 //FileTimeToDosDateTime(&ftCreate, &fdate, &ftime);
377 //status.createTime = __MakeTTime(fdate, ftime);
378 status.createTime = TTime(ftCreate);
379 //FileTimeToDosDateTime(&ftWrite, &fdate, &ftime);
380 //status.modifyTime = __MakeTTime(fdate, ftime);
381 status.modifyTime = TTime(ftWrite);
382 //FileTimeToDosDateTime(&ftAccess, &fdate, &ftime);
383 //status.accessTime = __MakeTTime(fdate, ftime);
384 status.accessTime = TTime(ftAccess);
385 status.size = Length();
386
387 return true;
388}
389
390
391//////////////////////////////////////////////////////////////////////
392// class TFile
393// ~~~~~ ~~~~~
394//
395//
396//
397/// If ShouldClose is true the file is closed. If the Handle is not FileNull Handle
398/// is deleted. Buffer is deleted.
399//
401{
402 if(ShouldClose)
403 Close();
404 if(Handle != FileNull)
405 delete Handle;
406 delete[] Buffer;
407}
408
409
410// if TFileHandle not support Clone() will throw TXNotSupportedCall()
412{
413 if(ShouldClose)
414 Close();
415 if(Handle != FileNull)
416 delete Handle;
417 Handle = file.GetHandle()->Clone();
418 ShouldClose = true;
419
420 CHECK(Handle);
421
422 if(!Handle)
424}
425
426
427/// Opens file name with the given mode. Returns true if successful, false
428/// otherwise. Calling Open when the file is already open will fail.
430{
431 if(IsOpen())
432 return false;
434 if(!Handle->IsOpen()){
435 delete Handle;
437 }
438 ShouldClose = true;
439 return IsOpen();
440}
441
442//------------------------------------------------------------------------------
443
444/// Closes the file. Returns true if successful, false otherwise.
446{
447 if(IsOpen() && ShouldClose){
448 if(!Handle->Close())
449 return false;
450 }
451 if(Handle != FileNull)
452 delete Handle;
454 ShouldClose = false;
455 return true;
456}
457
458
459/// Performs any pending I/O functions. Returns true if successful; false otherwise.
461{
463 return Handle->Flush();
464}
465
466
467/// Locks count bytes, beginning at position of the file. Returns true if
468/// successful; false otherwise.
470{
472 return Handle->LockRange(position, count);
473}
474
475/// Unlocks the range at the given Position. Returns true if successful; false
476/// otherwise.
478{
480 return Handle->UnlockRange(position, count);
481}
482
483
484inline int binCVTCharMBF (uint8* src, uint8* dst, int /*type*/, int size, int count)
485{
486 memcpy(dst, src, count*size);
487 return count*size;
488}
489//------------------------------------------------------------------------------
490static int binCVTShortMBF(uint8* _src, uint8* _dst, int /*type*/, int size, int count)
491{
492 int retval = count*size;
493 uint16* src = reinterpret_cast<uint16*>(_src);
494 uint16* dst = reinterpret_cast<uint16*>(_dst);
495 while(count--)
496 *dst++ = SwapUint16(*src++);
497
498 return retval;
499}
500//------------------------------------------------------------------------------
501static int binCVTLongMBF(uint8* _src, uint8* _dst, int /*type*/, int size, int count)
502{
503 int retval = count*size;
504 uint32* src = reinterpret_cast<uint32*>(_src);
505 uint32* dst = reinterpret_cast<uint32*>(_dst);
506 while(count--)
507 *dst++ = SwapUint32(*src++);
508
509 return retval;
510}
511//------------------------------------------------------------------------------
512static int binCVTFloatMBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count)
513{
514 int retval = count*size;
515 uint32* src = reinterpret_cast<uint32*>(_src);
516 uint32* dst = reinterpret_cast<uint32*>(_dst);
517 while(count--)
518 *dst++ = SwapUint32(*src++);
519
520 return retval;
521}
522//------------------------------------------------------------------------------
523static int binCVTDoubleMBF (uint8*, uint8*, int, int, int)
524{
525 return 0;
526}
527//------------------------------------------------------------------------------
528static int binCVTInt64MBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count) //???????????????????
529{
530 int retval = count*size;
531 __i_uint32_32* src = reinterpret_cast<__i_uint32_32*>(_src);
532 __i_uint32_32* dst = reinterpret_cast<__i_uint32_32*>(_dst);
533 while(count--){
534 dst->Lo = SwapUint32(src->Hi);
535 dst->Hi = SwapUint32(src->Lo);
536 dst++;
537 src++;
538 }
539 return retval;
540}
541//------------------------------------------------------------------------------
542//------------------------------------------------------------------------------
543inline int binCVTCharLBF (uint8* src, uint8* dst, int /*type*/, int size, int count){
544 memcpy(dst, src, count*size);
545 return count*size;
546}
547//------------------------------------------------------------------------------
548static int binCVTShortLBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count)
549{
550 int retval = count*size;
551 uint16* src = reinterpret_cast<uint16*>(_src);
552 uint16* dst = reinterpret_cast<uint16*>(_dst);
553 while(count--)
554 *dst++ = SwapUint16(*src++);
555
556 return retval;
557}
558//------------------------------------------------------------------------------
559static int binCVTLongLBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count)
560{
561 int retval = count*size;
562 uint32* src = reinterpret_cast<uint32*>(_src);
563 uint32* dst = reinterpret_cast<uint32*>(_dst);
564 while(count--)
565 *dst++ = SwapUint32(*src++);
566
567 return retval;
568}
569//------------------------------------------------------------------------------
570static int binCVTFloatLBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count)
571{
572 int retval = count*size;
573 uint32* src = reinterpret_cast<uint32*>(_src);
574 uint32* dst = reinterpret_cast<uint32*>(_dst);
575 while(count--)
576 *dst++ = SwapUint32(*src++);
577
578 return retval;
579}
580//------------------------------------------------------------------------------
581static int binCVTDoubleLBF (uint8*, uint8*, int, int, int)
582{
583 return 0;
584}
585//------------------------------------------------------------------------------
586static int binCVTInt64LBF (uint8* _src, uint8* _dst, int /*type*/, int size, int count)
587{
588 int retval = count*size;
589 __i_uint32_32* src = reinterpret_cast<__i_uint32_32*>(_src);
590 __i_uint32_32* dst = reinterpret_cast<__i_uint32_32*>(_dst);
591 while(count--){
592 dst->Lo = SwapUint32(src->Hi);
593 dst->Hi = SwapUint32(src->Lo);
594 dst++;
595 src++;
596 }
597 return retval;
598}
599//------------------------------------------------------------------------------
600typedef int (*cvtDispatchFunc)(uint8*, uint8*, int, int, int); /* Dispatch table entry */
601static cvtDispatchFunc dispatchMBF[] = { /* MBF -> LBF */
602 nullptr, /* varEnd */
603 binCVTLongMBF, /* varPOINTER */
604 binCVTCharMBF, /* varCHAR */
605 binCVTCharMBF, /* varUCHAR */
606 binCVTShortMBF, /* varSHORT */
607 binCVTLongMBF, /* varLONG */
608 binCVTCharMBF, /* varINT8 */
609 binCVTShortMBF, /* varINT16 */
610 binCVTLongMBF, /* varINT32 */
611 binCVTShortMBF, /* varUSHORT */
612 binCVTLongMBF, /* varULONG */
613 binCVTCharMBF, /* varUINT8 */
614 binCVTShortMBF, /* varUINT16 */
615 binCVTLongMBF, /* varUINT32 */
616 binCVTFloatMBF, /* varFLOAT */
617 binCVTDoubleMBF, /* varDOUBLE */
618 binCVTInt64MBF, /* varINT64 */
619 binCVTInt64MBF, /* varUINT64r */
620};
621
622static cvtDispatchFunc dispatchLBF[] = { /* LBF -> MBF */
623 nullptr, /* varEnd */
624 binCVTLongLBF, /* varPOINTER */
625 binCVTCharLBF, /* varCHAR */
626 binCVTCharLBF, /* varUCHAR */
627 binCVTShortMBF, /* varSHORT */
628 binCVTLongLBF, /* varLONG */
629 binCVTCharLBF, /* varINT8 */
630 binCVTShortMBF, /* varINT16 */
631 binCVTLongLBF, /* varINT32 */
632 binCVTShortLBF, /* varUSHORT */
633 binCVTLongLBF, /* varULONG */
634 binCVTCharLBF, /* varUINT8 */
635 binCVTShortLBF, /* varUINT16 */
636 binCVTLongLBF, /* varUINT32 */
637 binCVTFloatLBF, /* varFLOAT */
638 binCVTDoubleLBF, /* varDOUBLE */
639 binCVTInt64LBF, /* varINT64 */
640 binCVTInt64LBF, /* varUINT64r */
641};
642
643//------------------------------------------------------------------------------
644#define BINCHECKRTYPE(type) \
645 if ( (type) <= 0 || (type) > varLastMember) \
646 return 0;
647
648#define BINCHECKWTYPE(type) \
649 if ((type) <= 0 || (type) > varLastMember) \
650 return 0;
651
652#define BINCHECKNBYTES(nBytes) \
653 if((nBytes) <= 0 ) \
654 return 0;
655//------------------------------------------------------------------------------
656/// Returns the number of bytes in a binary data structure.
658{
659 uint count = 0;
660 for(TBinField *bfp = fields; bfp->Count; bfp++)
661 count += bfp->Count*bfp->Bytes;
662 return count;
663}
664//------------------------------------------------------------------------------
665/// Read binary structure from file.
666/// Returns # of bytes read
668{
669 TBinField *bfp; /* Field pointer */
670 uint count; /* Number of bytes read */
671 int n; /* Read status & # bytes read */
675 // int (*dispatch)(uint8*, uint8*, int, int, int ); /* Dispatch table entry */
676
677 /* Check all values in the fields array before doing anything. */
678 for(bfp = fields; bfp->Count; bfp++ ) {
679 BINCHECKRTYPE(bfp->Type);
680 BINCHECKNBYTES(bfp->Bytes)
681 }
682 // count size of structure
683 count = StructSize(fields);
684
685 // if no conversion
686 if(EndianType() == type)
687 return static_cast<uint>(Read(buffer, count));
688
689 // if Litle endian machine -> read as Big endian -> last choise
690 // else as Little endian
691 binReadDisp = dispatchMBF;
692 if(EndianType() == boBig_Endian)
693 binReadDisp = dispatchLBF;
694
695 if(Buffer && BufSize < count){
696 delete[] Buffer;
697 Buffer = nullptr;
698 }
699
700 if(!Buffer){
701 BufSize = count*5;
702 Buffer = new uint8[BufSize];
703 }
704
705 if(!Read(Buffer, count))
706 return 0;
707
708 count = 0;
710 for(bfp = fields; bfp->Count; bfp++ ){
711 dispatch = binReadDisp[bfp->Type];
712 if ((n = (*dispatch)(curBuffer,static_cast<uint8*>(buffer), bfp->Type, bfp->Bytes, bfp->Count)) == -1)
713 return 0; /* Error occured */
714 count += n;
715 buffer = static_cast<uint8*>(buffer) + bfp->Bytes * bfp->Count;
716 curBuffer += n;
717 }
718 return count;
719}
720//------------------------------------------------------------------------------
721/// Writes structures to binary file based on fields description.
722/// Returns # of bytes written
724{
725 TBinField *bfp; /* Field pointer */
726 uint count; /* Number of bytes read */
727 int n; /* Read status & # bytes read */
731
732 /* Check all values in the fields array before doing anything. */
733 for(bfp = fields; bfp->Count; bfp++ ) {
734 BINCHECKRTYPE(bfp->Type);
735 BINCHECKNBYTES(bfp->Bytes)
736 }
737 // count size of structure
738 count = StructSize(fields);
739
740 // if no conversion
741 if(EndianType() == type)
742 return Write(buffer, count);
743
744 // if Litle endian machine -> read as Big endian -> last choise
745 // else as Little endian
746 binReadDisp = dispatchMBF;
747 if(EndianType() == boBig_Endian)
748 binReadDisp = dispatchLBF;
749
750 if(Buffer && BufSize < count){
751 delete[] Buffer;
752 Buffer = nullptr;
753 }
754
755 if(!Buffer){
756 BufSize = count*5;
757 Buffer = new uint8[BufSize];
758 }
759
760 count = 0;
762 for(bfp = fields; bfp->Count; bfp++ ){
763 dispatch = binReadDisp[bfp->Type];
764 if ((n = (*dispatch)(static_cast<uint8*>(buffer), curBuffer, bfp->Type, bfp->Bytes, bfp->Count)) == -1)
765 return 0; /* Error occured */
766 count += n;
767 buffer = static_cast<uint8*>(buffer) + bfp->Bytes * bfp->Count;
768 curBuffer += n;
769 }
770 return Write(Buffer, count);
771}
772//------------------------------------------------------------------------------
773/// Read binary structure from buffer.
774/// Returns # of bytes read
776{
777 TBinField *bfp; /* Field pointer */
778 int count; /* Number of bytes read */
779 int n; /* Read status & # bytes read */
783// int (*dispatch)(uint8*, uint8*, int, int, int ); /* Dispatch table entry */
784
785 /* Check all values in the fields array before doing anything. */
786 for(bfp = fields; bfp->Count; bfp++ ) {
787 BINCHECKRTYPE(bfp->Type);
788 BINCHECKNBYTES(bfp->Bytes)
789 }
790 // count size of structure
791 count = StructSize(fields);
792
793 // if no conversion
794 if(EndianType() == type){
795 memcpy(buffer, ReadBuf, count);
796 return count;
797 }
798
799 // if Litle endian machine -> read as Big endian -> last choise
800 // else as Little endian
801 binReadDisp = dispatchMBF;
802 if(EndianType() == boBig_Endian)
803 binReadDisp = dispatchLBF;
804
805 count = 0;
807 for(bfp = fields; bfp->Count; bfp++ ){
808 dispatch = binReadDisp[bfp->Type];
809 if ((n = (*dispatch)(curBuffer,static_cast<uint8*>(buffer), bfp->Type, bfp->Bytes, bfp->Count)) == -1)
810 return 0; /* Error occured */
811 count += n;
812 buffer = static_cast<uint8*>(buffer) + bfp->Bytes * bfp->Count;
813 curBuffer += n;
814 }
815 return count;
816}
817//------------------------------------------------------------------------------
818/// Writes structures to buffer based on fields description.
819/// Returns # of bytes written
821{
822 TBinField *bfp; /* Field pointer */
823 int count; /* Number of bytes read */
824 int n; /* Read status & # bytes read */
828
829 /* Check all values in the fields array before doing anything. */
830 for(bfp = fields; bfp->Count; bfp++ ) {
831 BINCHECKRTYPE(bfp->Type);
832 BINCHECKNBYTES(bfp->Bytes)
833 }
834 // count size of structure
835 count = StructSize(fields);
836
837 // if no conversion
838 if(EndianType() == type){
839 memcpy(OutBuf, buffer, count);
840 return count;
841 }
842
843 // if Litle endian machine -> read as Big endian -> last choise
844 // else as Little endian
845 binReadDisp = dispatchMBF;
846 if(EndianType() == boBig_Endian)
847 binReadDisp = dispatchLBF;
848
849 count = 0;
851 for(bfp = fields; bfp->Count; bfp++ ){
852 dispatch = binReadDisp[bfp->Type];
853 if ((n = (*dispatch)(static_cast<uint8*>(buffer), curBuffer, bfp->Type, bfp->Bytes, bfp->Count)) == -1)
854 return 0; /* Error occured */
855 count += n;
856 buffer = static_cast<uint8*>(buffer) + bfp->Bytes * bfp->Count;
857 curBuffer += n;
858 }
859 return count;
860}
861
862
863static TBinField CharField[] = {
864 {varCHAR, 1, 1},
865 {varEnd, 0, 0},
866};
867static TBinField ShortField[] = {
868 {varSHORT, 2, 1},
869 {varEnd, 0, 0},
870};
871static TBinField LongField[] = {
872 {varLONG, 4, 1},
873 {varEnd, 0, 0},
874};
875static TBinField FloatField[] = {
876 {varFLOAT, 4, 1},
877 {varEnd, 0, 0},
878};
879static TBinField DoubleField[] = {
880 {varDOUBLE, 8, 1},
881 {varEnd, 0, 0},
882};
883static TBinField Long64Field[] = {
884 {varDOUBLE, 8, 1},
885 {varEnd, 0, 0},
886};
887static TBinField PointField[] = {
888 {varLONG, 4, 2},
889 {varEnd, 0, 0},
890};
891static TBinField RectField[] = {
892 {varLONG, 4, 2},
893 {varEnd, 0, 0},
894};
895static TBinField* FieldTypes[] = {
896 CharField,
897 ShortField,
898 LongField,
899 FloatField,
900 DoubleField,
901 Long64Field,
902 PointField,
903 RectField,
904};
905//------------------------------------------------------------------------------
906/// Read binary predefined structure from file.
907/// Returns # of bytes read
912//------------------------------------------------------------------------------
913/// Writes predefined structures to binary file.
918
919#if defined(OWL5_COMPAT) // must be moved to TFileName
920//
921/// Fills status with the status for name. Returns nonzero if successful, 0 otherwise.
922/// \note This is only available when OWL has been compiled with
923/// OWL5_COMPAT defined. The TFileName class should be used instead.
925{
926 return TFileName(name).GetStatus(status);
927}
928
929//
930/// Sets file name's status to status.
931/// \note This is only available when OWL has been compiled with OWL5_COMPAT
932/// defined. The TFileName class should be used instead.
933bool TFile::SetStatus(LPCTSTR name, const TFileStatus & status)
934{
935 return TFileName(name).SetStatus(status);
936}
937#endif //
938//
940{
941 int size = static_cast<int>(file.readUint32());
942 s = _T("");
943 s.resize(size+1);
944 if(file.Read(reinterpret_cast<void*>(const_cast<tchar*>(s.c_str())), size) == TFILE_ERROR)
945 size = -1;
946 s[size+1] = _T('\0');
947 return file;
948}
949
950
951
952uint8
954{
955 char c;
956 Read(&c, 1);
957 return c;
958}
959
960
961uint16
963{
964
965 uint16 i;
967 return i;
968}
969
970
971uint32
973 uint32 i;
975 return i;
976}
977
978
979uint64
985
986
987float
989{
990 float i;
992 return i;
993}
994
995
996double
998{
999 double i;
1001 return i;
1002}
1003
1004
1006{
1007 Write(&c, 1);
1008}
1009
1010
1012{
1013 WriteStruct(reinterpret_cast<void*>(const_cast<uint16*>(&i)), TypeShort, boLittle_Endian);
1014}
1015
1016
1017void
1019{
1020 WriteStruct(reinterpret_cast<void*>(const_cast<uint32*>(&i)), TypeLong, boLittle_Endian);
1021}
1022
1023
1024void
1026{
1027 WriteStruct(reinterpret_cast<void*>(const_cast<uint64*>(&i)), TypeLong64, boLittle_Endian);
1028}
1029
1030
1031void
1032TFile::writeFloat( const float f)
1033{
1034 WriteStruct(reinterpret_cast<void*>(const_cast<float*>(&f)), TypeFloat, boLittle_Endian);
1035}
1036
1037
1038void
1039TFile::writeDouble( const double d)
1040{
1041 WriteStruct(reinterpret_cast<void*>(const_cast<double*>(&d)), TypeDouble, boLittle_Endian);
1042}
1043
1044
1045//------------------------------------------------------------------------------
1046//
1047// TBufferedFile
1048// ~~~~~~~~~~~~~
1049
1050//
1051/// The buffer is flushed. If ShouldDelete is true the buffer is deleted.
1052//
1054{
1055 FlushBuffer();
1056 if(ShouldDelete)
1057 delete[] FileBuffer;
1058 FileBuffer = nullptr;
1059}
1060//------------------------------------------------------------------------------
1061/// Allocates a buffer of size bytes.
1063{
1064 BufferEmpty = true;
1065 EndPos = FileBufSize = size;
1066 CurByte = FileBuffer = new uint8[size];
1067 ShouldDelete = true;
1068 CurPos = StartPos = 0;
1069}
1070//------------------------------------------------------------------------------
1071/// Flushes the buffer by writing any unwritten data to the file. This function is
1072/// called by Flush() before the operating system is called to flush its buffers.
1074{
1075 // if open mode -> write flush buffer
1076 if(GetHandle() && (GetHandle()->GetOpenMode() & WriteOnly)){
1077 if(CurPos != StartPos){
1079 WARNX(OwlFileSystem,1, 0,"TBufferedFile::FlushBuffer() error Seek(), line: " << __LINE__);
1080 return false;
1081 }
1082 StartPos = CurPos;
1085 BufferEmpty = true;
1086 }
1087 }
1088 return true;
1089}
1090
1091
1092/// Flushes the current buffer and then deletes it if ShouldDelete is true. If
1093/// buffer is not NULL it is assigned to FileBuffer; otherwise FileBuffer is
1094/// allocated size bytes. ShouldDelete is then set.
1095//
1096void TBufferedFile::SetBuffer(uint8* buffer, uint size, bool shouldDelete)
1097{
1098 FlushBuffer();
1099 if(ShouldDelete)
1100 delete[] FileBuffer;
1101 ShouldDelete = shouldDelete;
1102 if(buffer)
1104 else{
1105 FileBuffer = CurByte = new uint8[size];
1106 ShouldDelete = true;
1107 }
1108 FileBufSize = size;
1109 // StartPos = CurPos; set in FlushBuffer
1111}
1112
1113
1114//
1115/// Repositions the file pointer to offset bytes from the specified
1116/// origin. If the position moved to is outside of the buffer, the buffer is
1117/// flushed. Returns the position moved to or TFILE64_ERROR on error. To get
1118/// extended error information, call LastError.
1119//
1121{
1123 // calculate absolute position ->
1125 if(origin == cur)
1126 position += offset;
1127 else if(origin == end)
1129 else
1130 position = offset;
1133 CurPos = static_cast<uint32>(position);
1135 }
1136 else{
1137 if(!FlushBuffer()){
1138 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Seek() error FlushBuffer(), line: " << __LINE__);
1139 return TFILE64_ERROR;
1140 }
1142 if(newpos != TFILE64_ERROR){
1143 StartPos = CurPos = static_cast<uint32>(position);
1146 BufferEmpty = true;
1147 }
1148 else{
1149 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Seek() error Seek(), line: " << __LINE__);
1150 return TFILE64_ERROR;
1151 }
1152 }
1153 return oldpos;
1154}
1155
1156
1157//
1158/// Repositions the file pointer to offset bytes from the specified origin. If the
1159/// position moved to is outside of the buffer, the buffer is flushed. Returns the
1160/// position moved to or TFILE_ERROR on error. To get extended error information,
1161/// call LastError.
1162//
1164{
1166 // calculate absolute position ->
1168 if(origin == cur)
1169 position += offset;
1170 else if(origin == end)
1171 position = Length() + offset;
1172 else
1173 position = offset;
1175 if(position >= StartPos && position < EndPos){
1176 CurPos = position;
1178 }
1179 else{
1180 if(!FlushBuffer()){
1181 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Seek() error FlushBuffer(), line: " << __LINE__);
1182 return TFILE_ERROR;
1183 }
1185 if(newpos != TFILE_ERROR){
1189 BufferEmpty = true;
1190 }
1191 else{
1192 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Seek() error Seek(), line: " << __LINE__);
1193 return TFILE_ERROR;
1194 }
1195 }
1196 return oldpos;
1197}
1198
1199
1200//
1201/// Reads numBytes from the file into buffer. The number of bytes read is returned.
1202//
1204{
1207 uint8* data = static_cast<uint8*>(buffer);
1208 // fill buffer if empty and buffer exist
1209 if(BufferEmpty && FileBufSize){
1210 StartPos = CurPos = Position();
1212 if(ret == TFILE_ERROR){
1213 WARNX(OwlFileSystem,ret==TFILE_ERROR, 0,"TBufferedFile::Write() error Read(), line: " << __LINE__);
1214 return ret;
1215 }
1217 EndPos = StartPos + ret;
1218 BufferEmpty = false;
1219 }
1220
1221 while(numBytes > 0){
1223 if(numBytes > dataSize){
1224 if(dataSize > 0){
1226 numBytes -= dataSize;
1227 data += dataSize;
1228 }
1229 uint32 ret;
1230 if(numBytes > FileBufSize){
1232 if(ret == TFILE_ERROR){
1233 WARNX(OwlFileSystem,ret==TFILE_ERROR, 0,"TBufferedFile::Write() error Read(), line: " << __LINE__);
1234 return ret;
1235 }
1236 BufferEmpty = true;
1237 numBytes = 0;
1238 }
1239 else{
1241 if(ret == TFILE_ERROR || ret == 0){
1242 if((buffer == data) && (ret == TFILE_ERROR)){
1243 WARNX(OwlFileSystem,ret==TFILE_ERROR, 0,"TBufferedFile::Write() error Read(), line: " << __LINE__);
1244 StartPos = CurPos;
1245 return ret;
1246 }
1247 else{
1249
1250 // Note: The number of read bytes should not exceed numBytes (uint32) so we can cast unchecked.
1251 // TODO: Widen the parameter and return type to avoid this narrowing cast.
1252
1253 size_t n = data - static_cast<uint8*>(buffer);
1254 return static_cast<uint32>(n);
1255 }
1256 }
1257 }
1258 StartPos = CurPos;
1259 EndPos = StartPos + ret;
1261 }
1262 else{
1264 data += numBytes;
1265 CurPos += numBytes;
1266 CurByte += numBytes;
1267 numBytes = 0;
1268 }
1269 }
1270 return retval;
1271}
1272
1273
1274/// Writes numBytes of buffer to the file. If numBytes is greater than the size of
1275/// the buffer the buffer is flushed and the data is written directly to the file;
1276/// if the amount of data in the buffer plus numBytes is greater than the capacity
1277/// of the buffer the buffer is filled and written to the file and the remaining
1278/// data is placed in the buffer; otherwise the data is appended to the buffer.
1279/// Returns true if the operation is successful; false otherwise.
1280//
1282{
1284 // if data size greater then buffer -> write directly
1285 if(numBytes > FileBufSize){
1286 if(!FlushBuffer()){
1287 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Write() error FlushBuffer(), line: " << __LINE__);
1288 return false;
1289 }
1291 return false;
1292 StartPos = CurPos = Position();
1295 return true;
1296 }
1297 // else use buffer for output
1298 uint8* data = static_cast<uint8*>(const_cast<void*>(buffer));
1299 while(numBytes > 0L){
1301 if( numBytes > freeSize ){
1303 numBytes -= freeSize;
1304 data += freeSize;
1305 CurPos += freeSize;
1307 WARNX(OwlFileSystem,1, 0,"TBufferedFile::Write() error Write(), line: " << __LINE__);
1308 return false;
1309 }
1310 StartPos = CurPos;
1313 }
1314 else{
1316 data += numBytes;
1317 CurByte += numBytes;
1318 CurPos += numBytes;
1319 numBytes = 0;
1320 }
1321 }
1322 return true;
1323}
1324
1325
1326//------------------------------------------------------------------------------
1327//
1328// TTextFile
1329// ~~~~~~~~~
1330
1331//
1332/// Reads up to size characters and places them in buffer. Normal termination is
1333/// when a \\r\\n character sequence is encountered. The string in buffer is NULL
1334/// terminated. NULL is returned on failure; a pointer to buffer is returned on
1335/// success.
1336//
1337LPTSTR
1339{
1341
1342 LPTSTR str = buffer;
1343 LPTSTR Buff = reinterpret_cast<LPTSTR>(CurByte);
1344 uint length = 0;
1345 if(BufferEmpty){
1346 StartPos = CurPos = Position();
1348 if(retval == TFILE_ERROR || retval == 0){
1349 WARNX(OwlFileSystem,retval==TFILE_ERROR,0,_T("TTextFile::GetString() error Read(), line: ") << __LINE__);
1350 return nullptr;
1351 }
1354 BufferEmpty = false;
1355 }
1356
1357 while(*Buff && *Buff != _T('\r') && *Buff != _T('\n') && length < size){
1358 // if end -> fill buffer
1359 if(CurPos >= EndPos){
1360 CurByte = reinterpret_cast<uint8*>(Buff);
1362 if((retval == TFILE_ERROR || retval == 0) && length==0){
1363 WARNX(OwlFileSystem,retval==TFILE_ERROR,0,_T("TTextFile::GetString() error Read(), line: ") <<__LINE__);
1364 return nullptr;
1365 }
1366 StartPos = CurPos;
1369 Buff = reinterpret_cast<LPTSTR>(CurByte);
1370 if(!retval)
1371 break;
1372 }
1373#if 0 // check UNICODE support
1374 *str = *Buff;
1375 LPTSTR p = CharNext(str);
1376 length += p - str;
1377 str = p;
1378 p = CharNext(Buff);
1379 uint delta = p - Buff;
1380 CurPos += delta;
1381 Buff += delta;
1382#else
1383 *str++ = *Buff++;
1384 length++;
1385 CurPos++;
1386#endif
1387 }
1388 if(*Buff == _T('\r')){
1389 Buff++;
1390 CurPos++;
1391 }
1392 if(*Buff == _T('\n')){
1393 Buff++;
1394 CurPos++;
1395 }
1396
1397 CurByte = reinterpret_cast<uint8*>(Buff);
1398
1399 // End string with 0
1400 *str = _T('\0');
1401 return (*CurByte || length) ? buffer : nullptr;
1402}
1403
1404namespace
1405{
1406
1407 //
1408 // For use with CopyText
1409 //
1410 struct TTextFileGetString
1411 {
1412 TTextFile& f;
1413 TTextFileGetString(TTextFile& f_) : f(f_) {}
1414 int operator()(LPTSTR buf, int bufSize)
1415 {
1416 LPTSTR r = f.GetString(buf, static_cast<uint32>(bufSize));
1417 return r ? bufSize - 1 : 0;
1418 }
1419 };
1420
1421} // namespace
1422
1423//
1424/// String-aware overload
1425//
1427{
1428 return CopyText(size, TTextFileGetString(*this));
1429}
1430
1431
1432//
1433/// Writes the NULL terminated character string in buffer to the file and adds a
1434/// terminating \\r\\n character sequence. The NULL character is not written. On
1435/// success true is returned; false otherwise.
1436//
1437bool
1439{
1441
1442 size_t len = ::_tcslen(buffer) * sizeof(tchar);
1443
1444 // TODO: Widen the parameter type for Write to avoid this check and the narrowing cast.
1445 //
1447 return false;
1448 bool status = TBufferedFile::Write(buffer, static_cast<uint32>(len));
1449 if(status)
1450 status = TBufferedFile::Write(_T("\r\n"), 2);
1451 return status;
1452}
1453
1454
1455uint8
1457{
1458 uint8 c;
1459 Read(&c, 1);
1460 return c;
1461}
1462
1463
1464uint16
1466{
1467 return static_cast<uint16>(readUint32());
1468}
1469
1470
1471uint32
1473{
1475 return 0; //?????????????????????????
1476}
1477uint64
1479{
1481 return 0; //?????????????????????????
1482}
1483
1484float
1486{
1487 return static_cast<float>(readDouble());
1488}
1489double
1491{
1493 return 0; //?????????????????????????
1494}
1495
1496
1497void
1499{
1500 Write(&u, 1);
1501}
1502
1503
1504void
1506{
1507 writeUint32(u);
1508}
1509
1510
1511void
1513{
1514 tchar buf[20];
1515#if defined __GNUC__
1516 _tprintf(buf, _T("%d"), u);
1517#else
1518 _ltot(u, buf, 10);
1519#endif
1520 Write(buf, static_cast<uint32>(::_tcslen(buf))); // TODO: Widen the paramteter type to avoid this narrowing cast.
1521 return;
1522}
1523
1524
1525void
1527{
1529 return; //?????????????????????????????
1530}
1531void
1533{
1534 writeDouble(f);
1535}
1536void
1538{
1540 return;//????????????????????????????????????????????
1541}
1542
1543
1544//
1545/// Constructor for iterating through file. The bufsize paramater is used for
1546/// setting the buffer size.
1547//
1549:
1550 File(&file),
1551 LineBuffer(nullptr),
1552 BuffSize(bufsize),
1553 LineNumber(0),
1554 Done(false)
1555{
1556 LineBuffer = new tchar[BuffSize];
1557 Done = !NextLine();
1558}
1559//------------------------------------------------------------------------------
1560/// Deletes the buffer.
1565//------------------------------------------------------------------------------
1566// all work do here -> must fill LineBuffer
1567//
1568/// Loads the next line in the file. Returns true if successful; false otherwise.
1569//
1571{
1572 if(!File || !File->IsOpen())
1573 return false;
1574 return ToBool(File->GetString(LineBuffer, BuffSize) != nullptr);
1575}
1576
1577
1578//------------------------------------------------------------------------------
1579
1580/// \cond
1581
1582#include <pshpack1.h>
1583struct __TChunk {
1584 uint32 CkId; // 'RIFF' or 'LIST'
1585 uint32 Size; // data size
1586 uint32 Type; // type for main chunk 'WAVE'
1587};
1588#include <poppack.h>
1589
1590/// \endcond
1591
1592//------------------------------------------------------------------------------
1593static TBinField ChunkField[] = {
1594 {varLONG, 4, 1}, /* FOURCC CkId; // 'RIFF' or 'LIST' */
1595 {varLONG, 4, 1}, /* data size */
1596 {varEnd, 0, 0},
1597};
1598//------------------------------------------------------------------------------
1599static TBinField ListField[] = {
1600 {varLONG, 4, 1}, /* FOURCC CkId; // 'RIFF' or 'LIST' */
1601 {varLONG, 4, 1}, /* data size */
1602 {varLONG, 4, 1}, /* type for main chunk 'WAVE' */
1603 {varEnd, 0, 0},
1604};
1605//------------------------------------------------------------------------------
1606// without first member
1607static TBinField ChunkField1[] = {
1608 {varLONG, 4, 1}, /* data size */
1609 {varEnd, 0, 0},
1610};
1611//------------------------------------------------------------------------------
1612static TBinField ListField1[] = {
1613 {varLONG, 4, 1}, /* data size */
1614 {varLONG, 4, 1}, /* type for main chunk 'WAVE' */
1615 {varEnd, 0, 0},
1616};
1617//------------------------------------------------------------------------------
1618/// Writes a data structure of the specified type to the associated file.
1620{
1621 CHECK(IsOpen());
1622
1624 chunk.CkId = 0;
1625 TBinField* fields = ListField;
1626
1627 info.Flags = TCkInfo::ckDirty;
1628 chunk.CkId = info.CkId; // type of Atom
1629 if(type == cfCreateList){
1630 chunk.CkId = FOURCC_LIST;
1631 info.Flags |= TCkInfo::ckList;
1632 }
1633 else if(type == cfCreateRiff){
1634 chunk.CkId = FOURCC_RIFF;
1635 info.Flags |= TCkInfo::ckRiff;
1636 }
1637
1638 chunk.Type = info.Type; // type of Atom
1639 chunk.Size = 0; // data size not include size of atom
1640
1641 if(type == cfCreateChunk)
1642 fields = ChunkField;
1643
1645 WARNX(OwlFileSystem,1, 0,"TRiffFile::CreateChunk() error WriteStruct(), line: " << __LINE__);
1646 return false;
1647 }
1648
1649 info.Offset = Position();
1650 if(type == cfCreateList || type == cfCreateRiff)
1651 info.Offset -= 4;
1652
1653 return true;
1654}
1655//------------------------------------------------------------------------------
1657{
1658 CHECK(IsOpen());
1659
1660 if(info.Flags & TCkInfo::ckDirty){
1661 info.Size = Position() - info.Offset;
1662 long offset = info.Offset - sizeof(__TChunk) + 4;
1663 if(Seek(offset, beg) == TFILE_ERROR){
1664 WARNX(OwlFileSystem,1, 0,"TRiffFile::Ascent() error Seek(), line: " << __LINE__);
1665 return false;
1666 }
1667
1669 chunk.CkId = info.CkId;
1670 chunk.Type = info.Type;
1671 chunk.Size = info.Size; // data size not include size of atom
1672
1673 if(info.Flags & TCkInfo::ckList)
1674 chunk.CkId = FOURCC_LIST;
1675 else if(info.Flags & TCkInfo::ckRiff)
1676 chunk.CkId = FOURCC_RIFF;
1677
1678 TBinField* fields = ChunkField;
1679 if(info.Flags & TCkInfo::ckList || info.Flags & TCkInfo::ckRiff)
1680 fields = ListField;
1681
1683 WARNX(OwlFileSystem,1, 0,"TRiffFile::Ascent() error WriteStruct(), line: " << __LINE__);
1684 return false;
1685 }
1686 info.Flags = 0;
1687 }
1688 // seek to beginning the next atom if any
1689 long size = info.Offset + info.Size;
1690 if(Seek(size, beg) == TFILE_ERROR){
1691 WARNX(OwlFileSystem,1, 0,"TRiffFile::Ascent() error Seek(), line: " << __LINE__);
1692 return false;
1693 }
1694
1695 return true;
1696}
1697/* -------------------------------------------------------------------------- */
1699{
1700 CHECK(IsOpen());
1701
1703
1704 if(flags & ffReset){
1705 if(parent){
1706 long offset = parent->Offset;
1707 if(parent->Flags & TCkInfo::ckList || parent->Flags & TCkInfo::ckRiff)
1708 offset += 4;
1709 if(Seek(offset, beg) == TFILE_ERROR){
1710 WARNX(OwlFileSystem,1, 0,"TRiffFile::Descent() error Seek(), line: " << __LINE__);
1711 return false;
1712 }
1713 }
1714 else // else if parent = 0
1715 if(SeekToBegin() == TFILE_ERROR){
1716 WARNX(OwlFileSystem,1, 0,"TRiffFile::Descent() error SeekToBegin(), line: " << __LINE__);
1717 return false;
1718 }
1719 }
1720
1721 bool bRiff;
1722 bool done = false;
1723 bool retval = false;
1724 uint32 riff, size;
1726 TBinField longField[] = { {varLONG, 4, 1}, {varEnd, 0, 0},};
1727
1728 do{
1730 WARNX(OwlFileSystem,1, 0,"TRiffFile::Descent() error ReadStruct(), line: " << __LINE__);
1731 return false;
1732 }
1733
1734 fields = ChunkField1;
1735 chunk.CkId = riff;
1736 info.Flags = 0;
1737
1738 bRiff = false;
1739 if(riff == FOURCC_RIFF){
1740 info.Flags |= TCkInfo::ckRiff;
1741 bRiff = true;
1742 fields = ListField1;
1743 }
1744 else if(riff == FOURCC_LIST){
1745 info.Flags |= TCkInfo::ckList;
1746 bRiff = true;
1747 fields = ListField1;
1748 }
1749
1750 if(!ReadStruct(&chunk.Size, fields, boLittle_Endian)){
1751 WARNX(OwlFileSystem,1, 0,"TRiffFile::Descent() error ReadStruct(), line: " << __LINE__);
1752 return false;
1753 }
1754
1755 info.Offset = Position();
1756 if(bRiff)
1757 info.Offset -= 4;
1758
1759 info.Size = chunk.Size;
1760
1761 // if any atom
1762 if(flags & ffFindAny){
1763 info.CkId = chunk.CkId;
1764 info.Type = bRiff ? chunk.Type : 0;
1765 retval = true;
1766 break;
1767 }
1768 //if set flag FindChunk search it
1769 else if(flags & ffFindChunk && chunk.CkId == info.CkId){
1770 info.Type = 0;
1771 retval = true;
1772 break;
1773 }
1774 else if(flags & ffFindList && chunk.Type == info.Type){
1775 info.Type = chunk.Type;
1776 info.CkId = FOURCC_LIST;
1777 retval = true;
1778 break;
1779 }
1780 else if(flags & ffFindRiff && chunk.CkId == FOURCC_RIFF){
1781 info.Type = chunk.Type;
1782 info.CkId = FOURCC_RIFF;
1783 retval = true;
1784 break;
1785 }
1786
1787 size = chunk.Size;
1788 // if list chunk exclude size one field
1789 if(bRiff)
1790 size -= 4;
1791 if(Seek(static_cast<long>(size), cur) == TFILE_ERROR){
1792 done = true;
1793 retval = true;
1794 }
1795 }
1796 while(!done);
1797
1798 return retval;
1799}
1800
1801
1802/// \cond
1803
1804#if !defined(qtstruct_h)
1805#include <pshpack1.h>
1806struct __MacAtom {
1807 uint32 Size;
1808 uint32 Type;
1809};
1810static TBinField MacAtomFields[] = {
1811 {varLONG, 4, 1}, /* uint32 Size; */
1812 {varCHAR, 1, 4}, /* uint32 Type; not swappable */
1813 {varEnd, 0, 0},
1814};
1815#include <poppack.h>
1816#endif
1817
1818/// \endcond
1819
1820/* -------------------------------------------------------------------------- */
1821bool TQtFile::Descent(TQtInfo& info, TQtInfo* parent, const TFindFlags flags)
1822{
1823 CHECK(IsOpen());
1824
1826
1827 uint32 position = 0;
1829
1830 if(flags & ffReset){
1831 if(parent){
1832 if(Seek(static_cast<long>(parent->Offset), beg) == TFILE_ERROR){
1833 WARNX(OwlFileSystem,1, 0,"TQtFile::Descent() error seek line: " << __LINE__);
1834 return false;
1835 }
1836 max_size = parent->Size + parent->Offset;
1837 position = parent->Offset;
1838 }
1839 else{ // else if parent = 0
1840 max_size = Length();
1841 if(SeekToBegin() == TFILE_ERROR){
1842 WARNX(OwlFileSystem,1, 0,"TQtFile::Descent() error seek to begin line: " << __LINE__);
1843 return false;
1844 }
1845 }
1846 }
1847 else{
1848 position = Position();
1849 if(parent)
1850 max_size = parent->Size + parent->Offset - position;
1851 else // else if parent = 0
1852 max_size = Length();
1853 }
1854 bool done = false;
1855 bool status = false;
1856
1857 do{
1859 if(atom.Type == info.Type){
1860 info.Size = atom.Size;
1861 info.Offset = Position();
1862 info.Flags = 0;
1863 status = true;
1864 done = true;
1865 }
1866 //if set flag FindChunk search it
1867 if(atom.Type != info.Type && flags & ffFindChunk){
1868 if (atom.Size==0 ||
1869 Seek(long(atom.Size-sizeof(atom)),cur)==TFILE_ERROR)
1870 done = true;
1871 position += atom.Size;
1872 }
1873 else
1874 done = true;
1875 }
1876 else
1877 done = true;
1878 }
1879 while(!done && position < max_size);
1880
1881 return status;
1882}
1883//------------------------------------------------------------------------------
1885{
1886 CHECK(IsOpen());
1887 if(info.Flags & TQtInfo::qtDirty){
1888 info.Size = Position() - info.Offset + sizeof(__MacAtom);
1889 long offset = info.Offset - sizeof(__MacAtom);
1890 if(Seek(offset, beg)==TFILE_ERROR){
1891 WARNX(OwlFileSystem,1, 0,"TQtFile::Ascent() error seek, line: " << __LINE__);
1892 return false;
1893 }
1894
1896 atom.Type = info.Type; // type of Atom
1897 atom.Size = info.Size; // data size include size of atom
1899 WARNX(OwlFileSystem,1, 0,"TQtFile::Ascent() error write to file, line: " << __LINE__);
1900 return false;
1901 }
1902 info.Flags = 0;
1903 }
1904 // seek to beginning the next atom if any
1905 return ToBool(Seek(long(info.Size+info.Offset-sizeof(__MacAtom)), beg) != TFILE_ERROR);
1906}
1907// -----------------------------------------------------------------------------
1908/// Writes a data structure of the specified type to the associated file.
1910{
1911 CHECK(IsOpen());
1912
1914 info.Flags = TQtInfo::qtDirty;
1915 atom.Type = info.Type; // type of Atom
1916 atom.Size = 0; // data size not include size of atom
1917
1919 WARNX(OwlFileSystem,1, 0,"TQtFile::CreateChunk() error write to file, line: " << __LINE__);
1920 return false;
1921 }
1922
1923 info.Offset = Position();
1924 return ToBool(info.Offset != TFILE_ERROR);
1925}
1926
1927
1928// -----------------------------------------------------------------------------
1929static void sys2StrmMode(int& uMode, uint32 openMode)
1930{
1931 if(!(openMode & TFile::Text))
1932 uMode |= ios::binary;
1934 uMode |= ios::in|ios::out;
1937 uMode |= ios::app;
1938 }
1939 else if(openMode & TFile::ReadOnly)
1940 uMode |= ios::in;
1941 else if(openMode & TFile::WriteOnly)
1942 uMode |= ios::out;
1943
1947 uMode |= ios::trunc; // create
1948}
1949// -----------------------------------------------------------------------------
1950// class TStreamHandle
1951// ~~~~~ ~~~~~~~~~~~~~
1952//
1953//
1955:
1956 Parent(parent),
1957 FileName(fileName),
1958 OpenMode(mode)
1959{
1960 // fstream
1961 int uMode = 0;
1962 sys2StrmMode(uMode, mode);
1964 Parent->open(_W2A(fileName.c_str()), static_cast<ios::openmode>(uMode));
1965}
1966//
1968{
1969 return Parent->bad();
1970}
1971//
1973{
1974 return Parent->rdbuf()->is_open();
1975}
1976//
1979{
1981 return nullptr;//????????????????????????????????
1982}
1983//
1985{
1986 if(Parent->rdbuf()->close() == nullptr)
1987 return false;
1988 return true;
1989}
1990//
1992{
1993 Parent->read(static_cast<tchar*>(buffer), numBytes/sizeof(tchar));
1994 streamsize n = Parent->gcount();
1995
1996 // Note: n cannot be greater than numBytes, so we can cast unchecked.
1997 // TODO: Widen the parameter and return type to avoid this narrowing cast.
1998 //
1999 return Parent->fail() == 0 ? numBytes : static_cast<uint32>(n);
2000}
2001//
2003{
2004 Parent->write(static_cast<const tchar *>(buffer), numBytes/sizeof(tchar));
2005 return Parent->fail()==0 ? true : false;
2006}
2007//
2009{
2010 return Length(static_cast<uint32>(newLen));
2011}
2012//
2014{
2016 if(retval==TFILE_ERROR)
2017 return TFILE64_ERROR;
2018 return uint64(retval);
2019}
2020//
2022{
2023 return uint64(Length());
2024}
2025//
2027{
2028// if(chsize((uint)Handle->GetHandle(), (long)newLen) != TFILE_ERROR)
2029// return true;
2030 TXNotSupportedCall::Raise();//?????????????????????????????
2031 return false;
2032}
2033//
2035{
2038 retval = Parent->tellp();
2039 else
2040 retval = Parent->tellg();
2041 if(retval == streampos(-1))
2042 return TFILE_ERROR;
2043 return static_cast<uint32>(retval);
2044}
2045//
2047{
2049 streampos retval = Parent->tellp();
2050 if(retval == streampos(-1))
2051 return TFILE_ERROR;
2052 return static_cast<uint32>(retval);
2053 }
2054 uint32 last_pos = (const_cast<TStreamHandle*>(this))->Seek(0l, TFile::end);
2055 uint32 pos = Position();
2056 (const_cast<TStreamHandle*>(this))->Seek(static_cast<long>(last_pos), TFile::beg);
2057 return pos;
2058}
2059//
2061{
2062 return uint64(Seek(static_cast<long>(offset), origin));
2063}
2064//
2066{
2069 Parent->seekp(static_cast<streamoff>(offset), static_cast<ios::seekdir>(origin));
2070 else
2071 Parent->seekg(static_cast<streamoff>(offset), static_cast<ios::seekdir>(origin));
2072 return position;
2073}
2074//
2076{
2078 Parent->flush();
2079 return true;
2080}
2081//
2082bool TStreamHandle::LockRange(uint32 /*position*/, uint32 /*count*/)
2083{
2085 return false;
2086}
2087//
2088bool TStreamHandle::UnlockRange(uint32 /*position*/, uint32 /*count*/)
2089{
2091 return false;
2092}
2093//
2094//
2096{
2097 return LockRange(static_cast<uint32>(position), static_cast<uint32>(count));
2098}
2099//
2101{
2102 return UnlockRange(static_cast<uint32>(position), static_cast<uint32>(count));
2103}
2104
2106{
2108 return false;
2109}
2110
2111
2112// -----------------------------------------------------------------------------
2113//
2114// TStreamFile in work
2115// ~~~~~~~~~~~
2116//
2117//------------------------------------------------------------------------------
2119{
2120 if(IsOpen())
2121 return false;
2122 Handle = new TStreamHandle(this, fileName, mode);
2123 if(!Handle->IsOpen()){
2124 delete reinterpret_cast<TStreamFile*>(Handle);
2125 Handle = FileNull;
2126 }
2127 return IsOpen();
2128}
2129//------------------------------------------------------------------------------
2130
2131} // OWL namespace
2132////////////////////////////////////////////////////////////////////////////////
2133////////////////////////////////////////////////////////////////////////////////
2134
#define CHECK(condition)
Definition checks.h:239
#define WARNX(group, condition, level, message)
Definition checks.h:277
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DEFINE_GROUP_INIT(f, g, e, l)
Definition checks.h:429
virtual uint32 Read(void *buffer, uint32 numBytes)
Reads numBytes from the file into buffer. The number of bytes read is returned.
Definition file.cpp:1203
virtual uint32 Length() const
Returns the file length plus the length of unwritten data in the buffer.
Definition file.h:1110
virtual ~TBufferedFile()
The buffer is flushed. If ShouldDelete is true the buffer is deleted.
Definition file.cpp:1053
virtual bool Write(const void *buffer, uint32 numBytes)
Writes numBytes of buffer to the file.
Definition file.cpp:1281
uint32 EndPos
Offset in file to the last data byte in the buffer.
Definition file.h:425
virtual bool FlushBuffer()
Flushes the buffer by writing any unwritten data to the file.
Definition file.cpp:1073
uint8 * CurByte
Pointer to current position in the buffer.
Definition file.h:416
virtual uint64 Length64() const
Returns the file length plus the length of unwritten data in the buffer.
Definition file.h:1096
virtual void InitBuffer(uint size=DefaultBufferSize)
Allocates a buffer of size bytes.
Definition file.cpp:1062
uint FileBufSize
Size of FileBuffer in bytes.
Definition file.h:413
uint8 * FileBuffer
Buffer used to store data in.
Definition file.h:407
bool BufferEmpty
True if the buffer is empty; false otherwise.
Definition file.h:428
uint32 StartPos
Offset in file to byte 0 of the buffer.
Definition file.h:422
virtual uint64 Seek(int64 offset, TSeekDir origin=beg)
Repositions the file pointer to offset bytes from the specified origin.
Definition file.cpp:1120
virtual uint32 Position() const
Returns the current position of the file pointer.
Definition file.h:1106
uint32 CurPos
Offset in file to current position.
Definition file.h:419
bool ShouldDelete
True if the buffer should be deleted.
Definition file.h:410
virtual void SetBuffer(uint8 *buffer, uint size, bool shouldDelete=true)
Flushes the current buffer and then deletes it if ShouldDelete is true.
Definition file.cpp:1096
TDiskFileHandle * Clone() const
Definition file.cpp:147
virtual bool UnlockRange(uint32 position, uint32 count)
Definition file.cpp:285
virtual bool Flush()
Definition file.cpp:271
virtual uint64 Seek(int64 offset, TFile::TSeekDir origin=TFile::beg)
Definition file.cpp:253
virtual bool Write(const void *buffer, uint32 numBytes)
Definition file.cpp:185
virtual bool Close()
Definition file.cpp:166
virtual uint64 Position64() const
Definition file.cpp:206
virtual bool LockRange(uint32 position, uint32 count)
Definition file.cpp:279
tstring FileName
Definition file.h:356
virtual bool GetStatus(TFileStatus &status) const
Definition file.cpp:359
TDiskFileHandle(const tstring &fileName, uint32 mode)
Definition file.cpp:122
virtual uint32 Read(void *buffer, uint32 numBytes)
Definition file.cpp:175
virtual uint32 LastError()
Definition file.cpp:159
virtual uint64 Length64() const
Definition file.cpp:214
virtual uint32 Length() const
Definition file.cpp:244
virtual uint32 Position() const
Definition file.cpp:234
virtual bool LockRange(uint32 position, uint32 count)=0
virtual bool IsOpen()=0
virtual bool UnlockRange(uint32 position, uint32 count)=0
virtual bool Close()=0
virtual bool Flush()=0
The TFile class encapsulates standard file characteristics and operations.
Definition file.h:120
virtual bool Open(const tstring &fileName, const uint32 mode=ReadOnly|PermRead|OpenExisting)
Opens file name with the given mode.
Definition file.cpp:429
bool IsOpen() const
Returns true if the file is open, false otherwise.
Definition file.h:755
virtual uint64 readUint64()
Definition file.cpp:980
uint BufSize
Size of Buffer used with structure read/write.
Definition file.h:275
virtual uint64 Seek(int64 offset, TSeekDir origin=beg)
Repositions the file pointer to offset bytes from the specified origin.
Definition file.h:875
bool ShouldClose
Should C++ object close file on dtor.
Definition file.h:267
@ Text
type Text are used in derived classes only default type is Binary
Definition file.h:158
@ PermWrite
Subsequent open operations on the object will succeed only if write access is requested.
Definition file.h:135
@ ReadOnly
Definition file.h:130
@ WriteOnly
Definition file.h:131
@ CreateNew
Creates a new file. The function fails if the specified file already exists.
Definition file.h:145
@ TruncateExist
Opens the file.
Definition file.h:156
@ OpenExisting
Opens the file. The function fails if the file does not exist.
Definition file.h:151
@ PermRead
Subsequent open operations on the object will succeed only if read access is requested.
Definition file.h:138
@ PermExclusive
Definition file.h:141
@ ReadWrite
Definition file.h:132
@ CreateAlways
Creates a new file. The function overwrites the file if it exists.
Definition file.h:148
uint8 * Buffer
Buffer used with structure read/write.
Definition file.h:272
virtual bool Flush()
Performs any pending I/O functions. Returns true if successful; false otherwise.
Definition file.cpp:460
virtual double readDouble()
Definition file.cpp:997
virtual bool LockRange(uint32 position, uint32 count)
Locks count bytes, beginning at position of the file.
Definition file.cpp:469
virtual void writeUint8(const uint8)
Definition file.cpp:1005
virtual uint32 Read(void *buffer, uint32 numBytes)
Reads numBytes from the file into buffer. The number of bytes read is returned.
Definition file.h:805
uint WriteStruct(void *buffer, TBinType btype, TByteOrderType type)
Writes predefined structures to binary file.
Definition file.cpp:914
virtual float readFloat()
Definition file.cpp:988
virtual void writeFloat(const float)
Definition file.cpp:1032
virtual uint16 readUint16()
Definition file.cpp:962
virtual uint32 readUint32()
Definition file.cpp:972
TFileHandle * Handle
Low-level C file handle.
Definition file.h:266
virtual bool Write(const void *buffer, uint32 numBytes)
Writes numbytes of buffer to the file.
Definition file.h:813
virtual bool UnlockRange(uint32 position, uint32 count)
Unlocks the range at the given Position.
Definition file.cpp:477
virtual void writeDouble(const double)
Definition file.cpp:1039
uint ReadStruct(void *buffer, TBinType btype, TByteOrderType type)
Read binary predefined structure from file.
Definition file.cpp:908
virtual ~TFile()
If ShouldClose is true the file is closed.
Definition file.cpp:400
uint32 GetOpenMode() const
Returns OpenMode.
Definition file.h:760
@ RdOnly
Definition file.h:165
@ Temporary
Definition file.h:171
@ Hidden
Definition file.h:166
@ Normal
Definition file.h:164
@ Directory
Definition file.h:169
@ Archive
Definition file.h:170
@ System
Definition file.h:167
static uint StructSize(TBinField *fields)
Returns the number of bytes in a binary data structure.
Definition file.cpp:657
uint32 SeekToBegin()
Repositions the file pointer to the beginning of the file.
Definition file.h:769
virtual uint8 readUint8()
Definition file.cpp:953
TFile()
Creates a TFile object with a file handle of FileNull.
Definition file.h:715
virtual void writeUint16(const uint16)
Definition file.cpp:1011
TBinType
Binary data type enumerations.
Definition file.h:175
@ TypeLong
Definition file.h:178
@ TypeLong64
Definition file.h:181
@ TypeFloat
Definition file.h:179
@ TypeShort
Definition file.h:177
@ TypeDouble
Definition file.h:180
virtual void writeUint32(const uint32)
Definition file.cpp:1018
virtual TFileHandle * GetHandle() const
Returns Handle.
Definition file.h:743
@ cur
Seek from the current position in the file.
Definition file.h:124
@ end
Seek from the end of the file.
Definition file.h:125
@ beg
Seek from the beginning of the file.
Definition file.h:123
virtual bool Close()
Closes the file. Returns true if successful, false otherwise.
Definition file.cpp:445
virtual void writeUint64(const uint64)
Definition file.cpp:1025
bool GetStatus(TFileStatus &status) const
Fills status with the current file status.
Definition file.h:899
virtual bool NextLine()
Loads the next line in the file. Returns true if successful; false otherwise.
Definition file.cpp:1570
TFileLineIterator()
Protected default constructor. Intializes everything to 0.
Definition file.h:1172
virtual ~TFileLineIterator()
Deletes the buffer.
Definition file.cpp:1561
TCHAR * LineBuffer
Buffer lines of text are loaded into.
Definition file.h:493
uint BuffSize
Size of the buffer allocated for loading a line of text.
Definition file.h:496
TTextFile * File
Pointer to the file being iterated through.
Definition file.h:490
The TFileName class constructs filenames.
Definition filename.h:37
int GetStatus(TFileStatus &status) const
Get the file status struct for the item associated with this filename.
TFileTime is a class derived from the structure FILETIME.
Definition wsyscls.h:362
bool Descent(TQtInfo &info, TQtInfo *parent=0, const TFindFlags=TFindFlags(ffFindChunk|ffReset))
Definition file.cpp:1821
@ ffFindChunk
Definition file.h:616
bool Ascent(TQtInfo &info)
Definition file.cpp:1884
bool CreateChunk(TQtInfo &info)
Writes a data structure of the specified type to the associated file.
Definition file.cpp:1909
bool Ascent(TCkInfo &info)
Definition file.cpp:1656
bool CreateChunk(TCkInfo &info, const TCreateFlags=cfCreateChunk)
Writes a data structure of the specified type to the associated file.
Definition file.cpp:1619
@ cfCreateChunk
Definition file.h:573
bool Descent(TCkInfo &info, TCkInfo *parent=0, const TFindFlags=ffFindAny)
Definition file.cpp:1698
virtual bool Open(const tstring &fileName, const uint32 mode=ReadOnly|PermRead|OpenExisting)
Definition file.cpp:2118
virtual uint32 LastError()
Definition file.cpp:1967
virtual bool Write(const void *buffer, uint32 numBytes)
Definition file.cpp:2002
virtual uint64 Seek(int64 offset, TFile::TSeekDir origin=TFile::beg)
Definition file.cpp:2060
virtual bool Flush()
Definition file.cpp:2075
virtual uint64 Position64() const
Definition file.cpp:2013
TStreamHandle(TStreamFile *parent, const tstring &filename, uint32 mode)
Definition file.cpp:1954
virtual bool LockRange(uint32 position, uint32 count)
Definition file.cpp:2082
virtual bool IsOpen()
Definition file.cpp:1972
virtual bool Close()
Definition file.cpp:1984
virtual uint32 Length() const
Definition file.cpp:2046
TStreamFile * Parent
Definition file.h:681
virtual uint64 Length64() const
Definition file.cpp:2021
TStreamHandle * Clone() const
Definition file.cpp:1978
virtual uint32 Position() const
Definition file.cpp:2034
virtual bool GetStatus(TFileStatus &status) const
Definition file.cpp:2105
virtual bool UnlockRange(uint32 position, uint32 count)
Definition file.cpp:2088
virtual uint32 Read(void *buffer, uint32 numBytes)
Definition file.cpp:1991
The TTextFile class is derived from TBufferedFile and encapsulates standard file characteristics and ...
Definition file.h:436
virtual double readDouble()
Definition file.cpp:1490
virtual uint32 readUint32()
Definition file.cpp:1472
virtual float readFloat()
Definition file.cpp:1485
virtual void writeUint64(const uint64)
Definition file.cpp:1526
virtual uint16 readUint16()
Definition file.cpp:1465
virtual uint64 readUint64()
Definition file.cpp:1478
virtual void writeUint8(const uint8)
Definition file.cpp:1498
virtual void writeUint32(const uint32)
Definition file.cpp:1512
virtual uint8 readUint8()
Definition file.cpp:1456
virtual void writeDouble(const double)
Definition file.cpp:1537
virtual TCHAR * GetString(TCHAR *buffer, uint32 size)
Reads up to size characters and places them in buffer.
Definition file.cpp:1338
virtual void writeFloat(const float)
Definition file.cpp:1532
virtual bool WriteString(LPCTSTR str)
Writes the NULL terminated character string in buffer to the file and adds a terminating \r\n charact...
Definition file.cpp:1438
virtual void writeUint16(const uint16)
Definition file.cpp:1505
The TTime class encapsulates time functions and characteristics.
Definition time.h:38
The TXBadFormat class is used for throwing exceptions when a bad file format is encountered.
Definition file.h:512
void Throw()
Definition file.cpp:78
TXBadFormat * Clone()
Definition file.cpp:69
static void Raise()
Construct a TXBadFormat exception from scratch, and throws it.
Definition file.cpp:62
TXBadFormat()
Constructs an exception handling class with identity IDS_BADFILEFORMAT.
Definition file.cpp:52
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
#define _ltot
Definition cygwin.h:63
#define _tfullpath
Definition cygwin.h:90
#define _tcslen
Definition cygwin.h:74
#define _T(x)
Definition cygwin.h:51
#define BINCHECKRTYPE(type)
Definition file.cpp:644
#define BINCHECKNBYTES(nBytes)
Definition file.cpp:652
static void Raise()
Definition except.cpp:326
TByteOrderType
The byte order type.
Definition file.h:48
#define TFILE_ERROR
Definition file.h:105
#define TFILE64_ERROR
Definition file.h:110
#define FileNull
Represents a NULL file handle.
Definition file.h:108
TByteOrderType EndianType()
Definition file.h:56
@ boLittle_Endian
LSB at lowest address: Intel //.
Definition file.h:49
@ boBig_Endian
MSB at lowest address: Motorola //.
Definition file.h:50
@ varCHAR
Definition file.h:71
@ varLONG
Definition file.h:74
@ varFLOAT
Definition file.h:83
@ varEnd
Definition file.h:69
@ varSHORT
Definition file.h:73
@ varDOUBLE
Definition file.h:84
#define _W2A(lpw)
Definition memory.h:219
#define _USES_CONVERSION
Definition memory.h:217
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
uint16 SwapUint16(uint16 u16)
Definition defs.h:288
__int64 int64
Definition number.h:36
signed long int32
Definition number.h:30
void __MakeDosTime(const TTime &time, uint16 &fdate, uint16 &ftime)
uint __sys2Atr(uint32 attrib)
Definition file.cpp:312
int binCVTCharLBF(uint8 *src, uint8 *dst, int, int size, int count)
Definition file.cpp:543
unsigned char uint8
Definition number.h:32
unsigned long uint32
Definition number.h:34
char tchar
Definition defs.h:77
tstring CopyText(int size, TGetText get_text)
Copies text from a C-string (null-terminated character array) into a string object,...
Definition defs.h:317
bool ToBool(const T &t)
Definition defs.h:291
int(* cvtDispatchFunc)(uint8 *, uint8 *, int, int, int)
Definition file.cpp:600
uint32 SwapUint32(uint32 u32)
Definition defs.h:291
OWL_DIAGINFO
Definition animctrl.cpp:14
TTime __MakeTTime(uint16 fdate, uint16 ftime)
unsigned __int64 uint64
Definition number.h:43
unsigned short uint16
Definition number.h:33
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
owl::ipstream & operator>>(owl::ipstream &is, TColor &c)
Extract the color value from a persistent input stream.
Definition color.h:489
int binCVTCharMBF(uint8 *src, uint8 *dst, int, int size, int count)
Definition file.cpp:484
uint __attr2Sys(uint attrib)
Definition file.cpp:331
#define OWL_INI
Definition defs.h:170
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376
The TBinField struct describes a group of like-typed fields in a structure to be read or written usin...
Definition file.h:98
RIFF chunk information data structure.
Definition file.h:541
uint32 Flags
flags used by MMIO functions
Definition file.h:554
uint32 Offset
offset of data portion of chunk
Definition file.h:553
uint32 size
Definition file.h:39
tchar fullName[_MAX_PATH]
Definition file.h:41
uint attribute
Definition file.h:40
TTime modifyTime
Definition file.h:37
TTime createTime
Definition file.h:36
TTime accessTime
Definition file.h:38
QuickTime atom information data structure.
Definition file.h:593
uint32 Offset
Definition file.h:600
uint32 Size
Definition file.h:598
Classes for window system structure and type encapsulation.