std::tuple<size_t, IOEvent> read_until_event(IInputStream& is, IOutputStream& os) { if (os.is_write_nonblocking()) { raise<IOError>("read_until_event will lose data if writing to non-blocking socket. Use a buffered approach instead."); } bool reading = true; size_t total_read = 0; size_t total_written = 0; IOEvent reason; byte buffer[1024]; while (reading) { auto r = is.read(buffer, 1024); either_switch(r, [&](size_t n) { total_written += n; either_switch(os.write(buffer, n), [&](size_t written) { total_written += written; }, [&](IOEvent wev) { reason = wev; reading = false; } ); }, [&](IOEvent event) { reason = event; reading = false; } ); } return {total_written, reason}; }
void CRPCServer::SocketReceived(CSocket *pSocket) { IInputStream *pInStream; int nResult; WaitForSingleObject(m_hMutex, INFINITE); pInStream = pSocket->GetInputStream(); while (pInStream->GetSize() > 0) { nResult = Process(pSocket->GetType(), pInStream, pSocket->GetOutputStream(), pSocket->GetRemoteAddress()); //process input data pSocket->Send(); //send response if (nResult != PRC_OK || pSocket->GetType() == SOCK_DGRAM) break; } ReleaseMutex(m_hMutex); }
ECode FileUtils::ChecksumCrc32( /* [in] */ IFile* file, /* [out] */ Int64* summer) { VALIDATE_NOT_NULL(file); VALIDATE_NOT_NULL(summer); *summer = 0; AutoPtr<ArrayOf<Byte> > buf; Int32 length; AutoPtr<ICRC32> checkSummer; CCRC32::New((ICRC32**)&checkSummer); AutoPtr<IFileInputStream> input; CFileInputStream::New(file, (IFileInputStream**)&input); IInputStream* is; AutoPtr<ICheckedInputStream> cis; ECode ec = CCheckedInputStream::New( IInputStream::Probe(input), IChecksum::Probe(checkSummer), (ICheckedInputStream**)&cis); FAIL_GOTO(ec, _EXIT_); is = IInputStream::Probe(cis); buf = ArrayOf<Byte>::Alloc(128); while(is->Read(buf, &length), length >= 0) { // Just read for checksum to get calculated. } IChecksum::Probe(checkSummer)->GetValue(summer); _EXIT_: if (cis != NULL) { ICloseable::Probe(cis)->Close(); } return ec; }
ECode FileUtils::ReadTextFile( /* [in] */ IFile* file, /* [in] */ Int32 max, /* [in] */ const String& ellipsis, /* [out] */ String* result) { VALIDATE_NOT_NULL(result); *result = String(""); VALIDATE_NOT_NULL(file); AutoPtr<IInputStream> input; AutoPtr<IBufferedInputStream> bis; Int64 size; Int32 length; AutoPtr<ArrayOf<Byte> > data, last, tmp; Boolean rolled = FALSE; AutoPtr<IByteArrayOutputStream> contents; IInputStream* is; IOutputStream* os; ECode ec = CFileInputStream::New(file, (IInputStream**)&input); FAIL_GOTO(ec, _EXIT_); // wrapping a BufferedInputStream around it because when reading /proc with unbuffered // input stream, bytes read not equal to buffer size is not necessarily the correct // indication for EOF; but it is true for BufferedInputStream due to its implementation. ec = CBufferedInputStream::New(input, (IBufferedInputStream**)&bis); FAIL_GOTO(ec, _EXIT_); is = IInputStream::Probe(bis); file->GetLength(&size); if (max > 0 || (size > 0 && max == 0)) { // "head" mode: read the first N bytes if (size > 0 && (max == 0 || size < max)) max = (Int32) size; data = ArrayOf<Byte>::Alloc(max + 1); is->Read(data, &length); if (length <= 0) { *result = String(""); } else if (length <= max) { *result = String((const char *)(data->GetPayload()), length); } else if (ellipsis.IsNull()) { *result = String((const char *)(data->GetPayload()), max); } else { *result = String((const char *)(data->GetPayload()), max); *result += ellipsis; } } else if (max < 0) { // "tail" mode: keep the last N do { if (last != NULL) rolled = true; tmp = last; last = data; data = tmp; if (data == NULL) data = ArrayOf<Byte>::Alloc(-max); is->Read(data, &length); } while (length == data->GetLength()); if (last == NULL && length <= 0) { *result = String(""); goto _EXIT_; } if (last == NULL) { *result = String((const char *)(data->GetPayload()), length); goto _EXIT_; } if (length > 0) { rolled = true; last->Copy(length, last, 0, last->GetLength() - length); last->Copy(last->GetLength() - length, data, 0, length); // System.arraycopy(last, length, last, 0, last.length - length); // System.arraycopy(data, 0, last, last.length - len, length); } if (ellipsis == NULL || !rolled) { *result = String((const char *)(last->GetPayload()), last->GetLength()); } else { *result = ellipsis; *result += String((const char *)(last->GetPayload()), last->GetLength()); } } else { // "cat" mode: size unknown, read it all in streaming fashion CByteArrayOutputStream::New((IByteArrayOutputStream**)&contents); os = IOutputStream::Probe(contents); data = ArrayOf<Byte>::Alloc(1024); do { is->Read(data, &length); if (length > 0) os->Write(data, 0, length); } while (length == data->GetLength()); contents->ToString(result); } _EXIT_: if (bis) ICloseable::Probe(bis)->Close(); if (input) ICloseable::Probe(input)->Close(); return ec; }
void TBmpFileBase::load_from(IInputStream& aInputStream,bool IsKeepAlpha) { long ReadPos=0; if (!checkHeadType(aInputStream)) this->raise_error("bmp file \"BM\" tag error!"); aInputStream.skip_trust(bmpTagSize); ReadPos+=bmpTagSize; //位图文件头结构和位图信息结构 BITMAPFILEHEADER_NO_TYPE bmFileHeader;//读出BITMAPFILEHEADER结构 memset(&bmFileHeader,0,sizeof(bmFileHeader)); aInputStream.read_trust((unsigned char *)&bmFileHeader,sizeof(bmFileHeader)); ReadPos+=sizeof(bmFileHeader); BITMAPINFOHEADER bmpInfo;// memset(&bmpInfo,0,sizeof(bmpInfo)); aInputStream.read_trust((unsigned char *)&bmpInfo.biSize,sizeof(bmpInfo.biSize)); aInputStream.read_trust((unsigned char *)&(((DWORD*)(&(bmpInfo.biSize)))[1]),STD::min((long)(sizeof(bmpInfo)-sizeof(DWORD)),(long)(bmpInfo.biSize-sizeof(DWORD)))); if (sizeof(bmpInfo)<bmpInfo.biSize) aInputStream.skip_trust(bmpInfo.biSize-sizeof(bmpInfo)); ReadPos+=bmpInfo.biSize; bool IsReFor=bmpInfo.biHeight>0; bmpInfo.biHeight=abs(bmpInfo.biHeight); DWORD nPalletteNumColors=0; if (bmpInfo.biBitCount<=8) { nPalletteNumColors=bmpInfo.biClrUsed; if (nPalletteNumColors==0 ) nPalletteNumColors=1 << bmpInfo.biBitCount; } long incBmpByteWidth=(((bmpInfo.biWidth*bmpInfo.biBitCount)+31) / (1<<5) ) << 2; if (bmpInfo.biSizeImage == 0) bmpInfo.biSizeImage = abs(incBmpByteWidth * bmpInfo.biHeight); RGBQUAD Pallette[256]; //调色板 if (nPalletteNumColors>0 ) { aInputStream.read_trust(&Pallette[0],nPalletteNumColors*sizeof(RGBQUAD)); ReadPos+=nPalletteNumColors*sizeof(RGBQUAD); for (long i=0; i<(long)nPalletteNumColors; ++i) Pallette[i].rgbReserved=0xFF; } else if (bmpInfo.biBitCount==16 ) { //区分 RGB 15bit,RGB 16bit if (bmpInfo.biCompression==BI_BITFIELDS ) { DWORD RMask,GMask,BMask; aInputStream.read_trust(&RMask,sizeof(DWORD)); aInputStream.read_trust(&GMask,sizeof(DWORD)); aInputStream.read_trust(&BMask,sizeof(DWORD)); ReadPos+=(3*sizeof(DWORD)); if (GMask==0x03E0 ) { bmpInfo.biBitCount=15; //assert(RMask==0x7C00); //assert(BMask==0x001F); } else { bmpInfo.biBitCount=16; //assert(RMask==0xF800); //assert(GMask==0x07E0); //assert(BMask==0x001F); } } else bmpInfo.biBitCount=15; } assert(bmpInfo.biPlanes==1); assert(bmpInfo.biCompression!=BI_RLE4);//不支持压缩格式 assert(bmpInfo.biCompression!=BI_RLE8);//不支持压缩格式 this->fast_resize(bmpInfo.biWidth,bmpInfo.biHeight); incBmpByteWidth=abs(incBmpByteWidth); aInputStream.skip_trust(bmFileHeader.bfOffBits-ReadPos); ReadPos=bmFileHeader.bfOffBits; UInt8* pLinePixels=(UInt8*)aInputStream.read_trust(bmpInfo.biSizeImage); ReadPos+=bmpInfo.biSizeImage; for (long y=0; y<bmpInfo.biHeight; ++y) { long py; if (IsReFor) py=bmpInfo.biHeight-1-y; else py=y; this->load_copy_line(pLinePixels,bmpInfo.biBitCount,(Color32 *)(&Pallette[0]),IsKeepAlpha,this->get_pixels_line(py)); pLinePixels+=incBmpByteWidth; } }
bool TBmpFileBase::checkHeadType(const IInputStream& aInputStream) { char tag[bmpTagSize]; if (!aInputStream.test_read(&tag[0],bmpTagSize)) return false; return ((tag[0]=='b')||(tag[0]=='B')) && ((tag[1]=='m')||(tag[1]=='M')); }
ssize_t InputStream_read(void *cookie, char *buf, size_t size) { IInputStream* input = (IInputStream*)cookie; return input->read(buf, size); }