Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: Multi-resolution Seamless Image Database (MrSID) 4 : * Purpose: Input/output stream wrapper for usage with LizardTech's 5 : * MrSID SDK, implementation of the wrapper class methods. 6 : * Author: Andrey Kiselev, dron@ak4719.spb.edu 7 : * 8 : ****************************************************************************** 9 : * Copyright (c) 2008, Andrey Kiselev <dron@ak4719.spb.edu> 10 : * Copyright (c) 2008-2010, Even Rouault <even dot rouault at spatialys.com> 11 : * 12 : * SPDX-License-Identifier: MIT 13 : ****************************************************************************/ 14 : 15 : #include "cpl_error.h" 16 : #include "mrsidstream.h" 17 : 18 : using namespace LizardTech; 19 : 20 : /************************************************************************/ 21 : /* ==================================================================== */ 22 : /* LTIVSIStream */ 23 : /* ==================================================================== */ 24 : /************************************************************************/ 25 : 26 62 : LTIVSIStream::LTIVSIStream() 27 62 : : poFileHandle(nullptr), nError(0), pnRefCount(nullptr), bIsOpen(FALSE) 28 : { 29 62 : } 30 : 31 : /************************************************************************/ 32 : /* ~LTIVSIStream() */ 33 : /************************************************************************/ 34 : 35 62 : LTIVSIStream::~LTIVSIStream() 36 : { 37 62 : if (poFileHandle) 38 : { 39 3 : (*pnRefCount)--; 40 3 : if (*pnRefCount == 0) 41 : { 42 3 : VSIFCloseL((VSILFILE *)poFileHandle); 43 3 : nError = errno; 44 3 : delete pnRefCount; 45 : } 46 : } 47 62 : } 48 : 49 : /************************************************************************/ 50 : /* initialize() */ 51 : /************************************************************************/ 52 : 53 3 : LT_STATUS LTIVSIStream::initialize(const char *pszFilename, 54 : const char *pszAccess) 55 : { 56 3 : CPLAssert(poFileHandle == nullptr); 57 : 58 3 : errno = 0; 59 3 : poFileHandle = (VSIVirtualHandle *)VSIFOpenL(pszFilename, pszAccess); 60 3 : if (poFileHandle) 61 : { 62 3 : pnRefCount = new int; 63 3 : *pnRefCount = 1; 64 : } 65 3 : nError = errno; 66 : 67 3 : return poFileHandle ? LT_STS_Success : LT_STS_Failure; 68 : } 69 : 70 : /************************************************************************/ 71 : /* initialize() */ 72 : /************************************************************************/ 73 : 74 0 : LT_STATUS LTIVSIStream::initialize(LTIVSIStream *ltiVSIStream) 75 : { 76 0 : CPLAssert(poFileHandle == nullptr); 77 : 78 0 : poFileHandle = ltiVSIStream->poFileHandle; 79 0 : if (poFileHandle) 80 : { 81 0 : pnRefCount = ltiVSIStream->pnRefCount; 82 0 : (*pnRefCount)++; 83 : } 84 : 85 0 : return poFileHandle ? LT_STS_Success : LT_STS_Failure; 86 : } 87 : 88 : /************************************************************************/ 89 : /* isEOF() */ 90 : /************************************************************************/ 91 : 92 0 : bool LTIVSIStream::isEOF() 93 : { 94 0 : CPLAssert(poFileHandle); 95 : 96 0 : errno = 0; 97 0 : bool bIsEOF = (poFileHandle->Eof() != 0 || poFileHandle->Error() != 0); 98 0 : nError = errno; 99 : 100 0 : return bIsEOF; 101 : } 102 : 103 : /************************************************************************/ 104 : /* isOpen() */ 105 : /************************************************************************/ 106 : 107 16 : bool LTIVSIStream::isOpen() 108 : { 109 16 : return poFileHandle != nullptr && bIsOpen; 110 : } 111 : 112 : /************************************************************************/ 113 : /* open() */ 114 : /************************************************************************/ 115 : 116 8 : LT_STATUS LTIVSIStream::open() 117 : { 118 8 : bIsOpen = poFileHandle != nullptr; 119 8 : return poFileHandle ? LT_STS_Success : LT_STS_Failure; 120 : } 121 : 122 : /************************************************************************/ 123 : /* close() */ 124 : /************************************************************************/ 125 : 126 8 : LT_STATUS LTIVSIStream::close() 127 : { 128 8 : CPLAssert(poFileHandle); 129 : 130 8 : bIsOpen = FALSE; 131 8 : errno = 0; 132 8 : if (poFileHandle->Seek(0, SEEK_SET) == 0) 133 8 : return LT_STS_Success; 134 : else 135 : { 136 0 : nError = errno; 137 0 : return LT_STS_Failure; 138 : } 139 : } 140 : 141 : /************************************************************************/ 142 : /* read() */ 143 : /************************************************************************/ 144 : 145 4101 : lt_uint32 LTIVSIStream::read(lt_uint8 *pDest, lt_uint32 nBytes) 146 : { 147 4101 : CPLAssert(poFileHandle); 148 : 149 4101 : errno = 0; 150 4101 : lt_uint32 nBytesRead = (lt_uint32)poFileHandle->Read(pDest, 1, nBytes); 151 4101 : nError = errno; 152 : 153 4101 : return nBytesRead; 154 : } 155 : 156 : /************************************************************************/ 157 : /* write() */ 158 : /************************************************************************/ 159 : 160 0 : lt_uint32 LTIVSIStream::write(const lt_uint8 *pSrc, lt_uint32 nBytes) 161 : { 162 0 : CPLAssert(poFileHandle); 163 : 164 0 : errno = 0; 165 0 : lt_uint32 nBytesWritten = (lt_uint32)poFileHandle->Write(pSrc, 1, nBytes); 166 0 : nError = errno; 167 : 168 0 : return nBytesWritten; 169 : } 170 : 171 : /************************************************************************/ 172 : /* seek() */ 173 : /************************************************************************/ 174 : 175 72 : LT_STATUS LTIVSIStream::seek(lt_int64 nOffset, LTIOSeekDir nOrigin) 176 : { 177 72 : CPLAssert(poFileHandle); 178 : 179 : int nWhence; 180 72 : switch (nOrigin) 181 : { 182 65 : case (LTIO_SEEK_DIR_BEG): 183 65 : nWhence = SEEK_SET; 184 65 : break; 185 : 186 4 : case (LTIO_SEEK_DIR_CUR): 187 : { 188 4 : nWhence = SEEK_CUR; 189 4 : if (nOffset < 0) 190 : { 191 0 : nWhence = SEEK_SET; 192 0 : nOffset += (lt_int64)poFileHandle->Tell(); 193 : } 194 4 : break; 195 : } 196 : 197 3 : case (LTIO_SEEK_DIR_END): 198 3 : nWhence = SEEK_END; 199 3 : break; 200 : 201 0 : default: 202 0 : return LT_STS_Failure; 203 : } 204 : 205 72 : if (poFileHandle->Seek((vsi_l_offset)nOffset, nWhence) == 0) 206 72 : return LT_STS_Success; 207 : else 208 : { 209 0 : nError = errno; 210 0 : return LT_STS_Failure; 211 : } 212 : } 213 : 214 : /************************************************************************/ 215 : /* tell() */ 216 : /************************************************************************/ 217 : 218 28 : lt_int64 LTIVSIStream::tell() 219 : { 220 28 : CPLAssert(poFileHandle); 221 : 222 28 : errno = 0; 223 28 : lt_int64 nPos = (lt_int64)poFileHandle->Tell(); 224 28 : nError = errno; 225 : 226 28 : return nPos; 227 : } 228 : 229 : /************************************************************************/ 230 : /* duplicate() */ 231 : /************************************************************************/ 232 : 233 0 : LTIOStreamInf *LTIVSIStream::duplicate() 234 : { 235 0 : LTIVSIStream *poNew = new LTIVSIStream; 236 0 : poNew->initialize(this); 237 : 238 0 : return poNew; 239 : } 240 : 241 : /************************************************************************/ 242 : /* getLastError() */ 243 : /************************************************************************/ 244 : 245 0 : LT_STATUS LTIVSIStream::getLastError() const 246 : { 247 0 : return nError; 248 : } 249 : 250 : /************************************************************************/ 251 : /* getID() */ 252 : /************************************************************************/ 253 : 254 2 : const char *LTIVSIStream::getID() const 255 : { 256 2 : return "LTIVSIStream:"; 257 : }