int GZDecompress(Stream& out, Stream& in, int size, Gate2<int, int> progress) { byte buffer[10]; if(!in.GetAll(buffer, 10) || buffer[0] != GZ_MAGIC1 || buffer[1] != GZ_MAGIC2) { out.SetError(); return -1; } int flags = buffer[3]; if(buffer[2] != Z_DEFLATED || (flags & RESERVED) != 0) return false; size -= 10; if(flags & EXTRA_FIELD) { int len = in.Get16le(); in.SeekCur(len); size -= len; } if(flags & ORIG_NAME) size -= sSkipZ(in); if(flags & COMMENT) size -= sSkipZ(in); if(flags & HEAD_CRC) { in.Get16le(); size -= 2; } if(in.IsEof() || size < 0) { out.SetError(); return -1; } dword crc; int sz = ZDecompress(out, in, size, progress, true, &crc); return sz < 0 || in.Get32le() != (int)crc || in.Get32le() != sz ? -1 : sz; }
NAMESPACE_UPP static void sLoadBom(Stream& in, String *t, WString *wt, byte def_charset) { if(in.IsOpen()) { String s; if(in.GetLeft() > 3) { word header = in.Get16le(); if(header == 0xfffe || header == 0xfeff) { int n = (int)in.GetLeft() / 2; WStringBuffer ws(n); ws.SetLength(in.Get(~ws, 2 * n) / 2); if(header == 0xfffe) EndianSwap((word *)~ws, ws.GetCount()); if(wt) *wt = ws; else *t = FromUnicode(ws); return; } int c = in.Get(); if(c < 0) return; byte *h = (byte *)&header; if(h[0] == 0xef && h[1] == 0xbb && c == 0xbf) { if(wt) *wt = FromUtf8(LoadStream(in)); else *t = ToCharset(CHARSET_DEFAULT, LoadStream(in), CHARSET_UTF8); return; } s.Cat(h, 2); s.Cat(c); } s.Cat(LoadStream(in)); if(wt) *wt = ToUnicode(s, def_charset); else *t = ToCharset(CHARSET_DEFAULT, s, def_charset); return; } return; }