1 /* 7zFile.c -- File IO
2    2009-11-24 : Igor Pavlov : Public domain */
3 
4 #include <stdint.h>
5 #define SKIP_STDIO_REDEFINES
6 #include <streams/file_stream_transforms.h>
7 #include "7zFile.h"
8 
9 #ifndef UNDER_CE
10 #include <errno.h>
11 #endif
12 
File_Construct(CSzFile * p)13 void File_Construct(CSzFile *p)
14 {
15    p->file = NULL;
16 }
17 
File_Open(CSzFile * p,const char * name,int writeMode)18 static WRes File_Open(CSzFile *p, const char *name, int writeMode)
19 {
20    p->file = rfopen(name, writeMode ? "wb+" : "rb");
21    if (!p->file)
22    {
23 #ifdef UNDER_CE
24       return 2; /* ENOENT */
25 #else
26       return errno;
27 #endif
28    }
29 
30    return 0;
31 }
32 
InFile_Open(CSzFile * p,const char * name)33 WRes InFile_Open(CSzFile *p, const char *name)
34 {
35    return File_Open(p, name, 0);
36 }
37 
OutFile_Open(CSzFile * p,const char * name)38 WRes OutFile_Open(CSzFile *p, const char *name)
39 {
40    return File_Open(p, name, 1);
41 }
42 
File_Close(CSzFile * p)43 WRes File_Close(CSzFile *p)
44 {
45    if (p->file)
46    {
47       int res = rfclose((RFILE*)p->file);
48       if (res != 0)
49          return res;
50       p->file = NULL;
51    }
52    return 0;
53 }
54 
File_Read(CSzFile * p,void * data,size_t * size)55 WRes File_Read(CSzFile *p, void *data, size_t *size)
56 {
57    int64_t originalSize = *size;
58    if (originalSize == 0)
59       return 0;
60 
61    *size = rfread(data, 1, originalSize, (RFILE*)p->file);
62    if (*size == originalSize)
63       return 0;
64    return rferror((RFILE*)p->file);
65 }
66 
File_Write(CSzFile * p,const void * data,size_t * size)67 WRes File_Write(CSzFile *p, const void *data, size_t *size)
68 {
69    int64_t originalSize = *size;
70    if (originalSize == 0)
71       return 0;
72 
73    *size = rfwrite(data, 1, originalSize, (RFILE*)p->file);
74    if (*size == originalSize)
75       return 0;
76    return rferror((RFILE*)p->file);
77 }
78 
File_Seek(CSzFile * p,int64_t * pos,ESzSeek origin)79 WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin)
80 {
81    int whence;
82    int64_t res;
83    switch (origin)
84    {
85       case SZ_SEEK_SET:
86          whence = SEEK_SET;
87          break;
88       case SZ_SEEK_CUR:
89          whence = SEEK_CUR;
90          break;
91       case SZ_SEEK_END:
92          whence = SEEK_END;
93          break;
94       default:
95          return 1;
96    }
97    res  = rfseek((RFILE*)p->file, (int64_t)*pos, whence);
98    *pos = rftell((RFILE*)p->file);
99    return res;
100 }
101 
File_GetLength(CSzFile * p,uint64_t * length)102 WRes File_GetLength(CSzFile *p, uint64_t *length)
103 {
104    int64_t pos  = rftell((RFILE*)p->file);
105    int64_t res  = rfseek((RFILE*)p->file, 0, SEEK_END);
106    *length      = rftell((RFILE*)p->file);
107    rfseek((RFILE*)p->file, pos, SEEK_SET);
108    return res;
109 }
110 
111 
112 /* ---------- FileSeqInStream ---------- */
113 
FileSeqInStream_Read(void * pp,void * buf,size_t * size)114 static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
115 {
116    CFileSeqInStream *p = (CFileSeqInStream *)pp;
117    return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
118 }
119 
FileSeqInStream_CreateVTable(CFileSeqInStream * p)120 void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
121 {
122    p->s.Read = FileSeqInStream_Read;
123 }
124 
125 /* ---------- FileInStream ---------- */
126 
FileInStream_Read(void * pp,void * buf,size_t * size)127 static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
128 {
129    CFileInStream *p = (CFileInStream *)pp;
130    return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
131 }
132 
FileInStream_Seek(void * pp,int64_t * pos,ESzSeek origin)133 static SRes FileInStream_Seek(void *pp, int64_t *pos, ESzSeek origin)
134 {
135    CFileInStream *p = (CFileInStream *)pp;
136    return File_Seek(&p->file, pos, origin);
137 }
138 
FileInStream_CreateVTable(CFileInStream * p)139 void FileInStream_CreateVTable(CFileInStream *p)
140 {
141    p->s.Read = FileInStream_Read;
142    p->s.Seek = FileInStream_Seek;
143 }
144 
145 
146 /* ---------- FileOutStream ---------- */
147 
FileOutStream_Write(void * pp,const void * data,size_t size)148 static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
149 {
150    CFileOutStream *p = (CFileOutStream *)pp;
151    File_Write(&p->file, data, &size);
152    return size;
153 }
154 
FileOutStream_CreateVTable(CFileOutStream * p)155 void FileOutStream_CreateVTable(CFileOutStream *p)
156 {
157    p->s.Write = FileOutStream_Write;
158 }
159 
160 #undef SKIP_STDIO_REDEFINES
161