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