bool ZWebDAV::sHandle_GET(const ZTrail& iPrefix, ZNode iRoot, const ZStreamR&, const ZStreamW& iStreamW, const ZTuple& iHeader, const ZTrail& iTrail, const ZTuple& iParam) { ZNode theNode = iRoot.Trail(iTrail); ZHTTP::Response r; r.Set("date", sAsString_WebDAV(ZTime::sNow())); if (iHeader.Has("range")) { if (const ZLog::S& s = ZLog::S(ZLog::eInfo, "ZWebDAV")) s << "GET with range:\n" << iHeader; } if (theNode.Exists()) { r.SetResult(200); if (theNode.CanHaveChildren()) { r.Set("Content-Type", "text/html; charset=\"utf-8\""); r.Set("Transfer-Encoding", "chunked"); r.Send(iStreamW); ZHTTP::StreamW_Chunked chunkedStream(iStreamW); ZStrimW_StreamUTF8 theStrimW(chunkedStream); ZStrimW_ML s(false, theStrimW); s.Begin("html"); s.Begin("title"); s << theNode.Name(); s.End("title"); s.Begin("body"); for (ZNodeIter i = theNode; i; i.Advance()) { s.Begin("p"); s.Begin("a"); if (i.Current().CanHaveChildren()) { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name()) + "/"); s << i.Current().Name() << "/"; } else { s.Attr("href", ZHTTP::sEncodeComponent(i.Current().Name())); s << i.Current().Name(); } s.End("a"); s.End("p"); } s.End("body"); s.End("html"); } else if (ZRef<ZStreamerRPos> theStreamer = theNode.OpenRPos()) { const ZStreamRPos& theStreamRPos = theStreamer->GetStreamRPos(); uint64 sentSize = theStreamRPos.GetSize(); if (ZTupleValue rangeParam = iHeader.GetValue("range")) { vector<pair<size_t, size_t> > ranges; if (!ZHTTP::sOrganizeRanges(sentSize, rangeParam, ranges)) { iStreamW.WriteString("HTTP/1.1 406 Unsatisfiable range\r\n\r\n"); return false; } r.SetResult(206, "Partial Content"); r.Set("Content-Range", ZString::sFormat("bytes %d-%d/%d", ranges.front().first, ranges.front().second - 1, sentSize)); theStreamRPos.SetPosition(ranges.front().first); sentSize = ranges.front().second - ranges.front().first; } else { r.SetResult(200); } string theMIMEType = "application/octet-stream"; ZTupleValue theMIMEValue; if (theNode.GetProp("MIMEType", theMIMEValue)) { string asString; if (theMIMEValue.GetString(asString)) theMIMEType = asString; } r.Set("Content-Type", theMIMEType); ZTupleValue theValue; if (theNode.GetProp("lastModified", theValue)) { if (ZTime theTime = theValue.GetTime()) r.Set("Last-Modified", sAsString_WebDAV(theTime)); } r.Set("Content-Transfer-Encoding", "binary"); r.Set("Content-Length", ZString::sFromUInt64(sentSize)); r.Send(iStreamW); iStreamW.CopyFrom(theStreamRPos, sentSize); } } else { r.SetResult(404); r.Send(iStreamW); r.Set("Content-Length", 0); } return true; }
void ZDCPixmapEncoder_GIF::Imp_Write(const ZStreamW& iStream, const void* iBaseAddress, const ZDCPixmapNS::RasterDesc& iRasterDesc, const ZDCPixmapNS::PixelDesc& iPixelDesc, const ZRect& iBounds) { ZRef<ZDCPixmapNS::PixelDescRep_Indexed> thePixelDescRep_Indexed = ZRefDynamicCast<ZDCPixmapNS::PixelDescRep_Indexed>(iPixelDesc.GetRep()); ZAssertStop(2, thePixelDescRep_Indexed); if (fTransparent) iStream.WriteString("GIF89a"); else iStream.WriteString("GIF87a"); iStream.WriteUInt16LE(iBounds.Width()); iStream.WriteUInt16LE(iBounds.Height()); uint8 globalStrmFlags = 0; globalStrmFlags |= 0x80; // hasGlobalColorTable globalStrmFlags |= 0x70; // colorResolution (8 bits per component) // globalStrmFlags |= 0x08; // set this if the color table is sorted in priority order ZAssertStop(2, iRasterDesc.fPixvalDesc.fDepth > 0 && iRasterDesc.fPixvalDesc.fDepth <= 8); globalStrmFlags |= iRasterDesc.fPixvalDesc.fDepth - 1; // globalColorTableSize & depth iStream.WriteUInt8(globalStrmFlags); iStream.WriteUInt8(0); // backgroundColorIndex iStream.WriteUInt8(0); // Pixel aspect ratio -- 0 == none specified. const ZRGBColorPOD* theColors; size_t theColorsCount; thePixelDescRep_Indexed->GetColors(theColors, theColorsCount); sWriteColorTable(iStream, theColors, theColorsCount, 1 << iRasterDesc.fPixvalDesc.fDepth); if (fTransparent) { iStream.WriteUInt8('!'); // Extension block iStream.WriteUInt8(0xF9); // Graphic Control Extension iStream.WriteUInt8(4); // Block size // The next byte encodes four fields: // 3 bits, Reserved == 0 // 3 bits, Disposal Method == none (0), // 1 bit, User Input Flag == none (0) // 1 bit, Transparent Color Flag = yes (1) iStream.WriteUInt8(1); iStream.WriteUInt16LE(0); // Delay time iStream.WriteUInt8(fTransparentPixval); iStream.WriteUInt8(0); // Block terminator } iStream.WriteUInt8(','); // Start of image iStream.WriteUInt16LE(0); // Origin h iStream.WriteUInt16LE(0); // Origin v iStream.WriteUInt16LE(iBounds.Width()); iStream.WriteUInt16LE(iBounds.Height()); uint8 localStrmFlags = 0; // localStrmFlags |= 0x80; // hasLocalColorTable if (fInterlace) localStrmFlags |= 0x40; // interlaced // localStrmFlags |= 0x20; // sorted // localStrmFlags |= 0x70; // localColorTableSize iStream.WriteUInt8(localStrmFlags); iStream.WriteUInt8(iRasterDesc.fPixvalDesc.fDepth); // Initial code size. { // Scope theSC. StreamW_Chunk theSC(iStream); ZStreamW_LZWEncode* theSLZW = nil; ZStreamW_LZWEncodeNoPatent* theSLZWNP = nil; ZStreamW* theStream; if (fNoPatent) { theSLZWNP = new ZStreamW_LZWEncodeNoPatent(iRasterDesc.fPixvalDesc.fDepth, theSC); theStream = theSLZWNP; } else { theSLZW = new ZStreamW_LZWEncode(iRasterDesc.fPixvalDesc.fDepth, theSC); theStream = theSLZW; } ZDCPixmapNS::PixvalDesc destPixvalDesc(8, true); vector<uint8> theRowBufferVector(iBounds.Width()); void* theRowBuffer = &theRowBufferVector[0]; try { if (fInterlace) { for (int pass = 0; pass < 4; ++pass) { for (ZCoord currentY = iBounds.top + sInterlaceStart[pass]; currentY < iBounds.bottom; currentY += sInterlaceIncrement[pass]) { const void* sourceRowAddress = iRasterDesc.CalcRowAddress(iBaseAddress, currentY); ZDCPixmapNS::sBlitRowPixvals( sourceRowAddress, iRasterDesc.fPixvalDesc, iBounds.left, theRowBuffer, destPixvalDesc, 0, iBounds.Width()); theStream->Write(theRowBuffer, iBounds.Width()); } } } else { for (ZCoord currentY = iBounds.top; currentY < iBounds.bottom; ++currentY) { const void* sourceRowAddress = iRasterDesc.CalcRowAddress(iBaseAddress, currentY); ZDCPixmapNS::sBlitRowPixvals( sourceRowAddress, iRasterDesc.fPixvalDesc, iBounds.left, theRowBuffer, destPixvalDesc, 0, iBounds.Width()); theStream->Write(theRowBuffer, iBounds.Width()); } } } catch (...) { delete theSLZW; delete theSLZWNP; throw; } delete theSLZW; delete theSLZWNP; } iStream.WriteUInt8(';'); // Trailer. }