static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) { int index = item.FindSubTag(name); if (index < 0) return false; const CXmlItem &checkItem = item.SubItems[index]; AString style = checkItem.GetPropertyValue("style"); if (style == "SHA1") { AString s = checkItem.GetSubString(); if (s.Length() != 40) return false; for (int i = 0; i < s.Length(); i += 2) { Byte b0, b1; if (!HexToByte(s[i], b0) || !HexToByte(s[i + 1], b1)) return false; digest[i / 2] = (b0 << 4) | b1; } return true; } return false; }
static bool ParseSha1(const CXmlItem &item, const char *name, Byte *digest) { int index = item.FindSubTag(name); if (index < 0) return false; const CXmlItem &checkItem = item.SubItems[index]; const AString style = checkItem.GetPropVal("style"); if (style == "SHA1") { const AString s = checkItem.GetSubString(); if (s.Len() != SHA1_DIGEST_SIZE * 2) return false; for (unsigned i = 0; i < s.Len(); i += 2) { int b0 = HexToByte(s[i]); int b1 = HexToByte(s[i + 1]); if (b0 < 0 || b1 < 0) return false; digest[i / 2] = (Byte)((b0 << 4) | b1); } return true; } return false; }
static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int parent) { if (!item.IsTag) return true; if (item.Name == "file") { CFile file; file.Parent = parent; parent = files.Size(); file.Name = item.GetSubStringForTag("name"); AString type = item.GetSubStringForTag("type"); if (type == "directory") file.IsDir = true; else if (type == "file") file.IsDir = false; else return false; int dataIndex = item.FindSubTag("data"); if (dataIndex >= 0 && !file.IsDir) { file.HasData = true; const CXmlItem &dataItem = item.SubItems[dataIndex]; if (!ParseUInt64(dataItem, "size", file.Size)) return false; if (!ParseUInt64(dataItem, "length", file.PackSize)) return false; if (!ParseUInt64(dataItem, "offset", file.Offset)) return false; file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); int encodingIndex = dataItem.FindSubTag("encoding"); if (encodingIndex >= 0) { const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; if (encodingItem.IsTag) { AString s = encodingItem.GetPropertyValue("style"); if (s.Length() >= 0) { AString appl = "application/"; if (s.Left(appl.Length()) == appl) { s = s.Mid(appl.Length()); AString xx = "x-"; if (s.Left(xx.Length()) == xx) { s = s.Mid(xx.Length()); if (s == "gzip") s = METHOD_NAME_ZLIB; } } file.Method = s; } } } } file.CTime = ParseTime(item, "ctime"); file.MTime = ParseTime(item, "mtime"); file.ATime = ParseTime(item, "atime"); files.Add(file); } for (int i = 0; i < item.SubItems.Size(); i++) if (!AddItem(item.SubItems[i], files, parent)) return false; return true; }
static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int parent) { if (!item.IsTag) return true; if (item.Name == "file") { CFile file; file.Parent = parent; parent = files.Size(); file.Name = item.GetSubStringForTag("name"); AString type = item.GetSubStringForTag("type"); if (type == "directory") file.IsDir = true; else if (type == "file") file.IsDir = false; else return false; int dataIndex = item.FindSubTag("data"); if (dataIndex >= 0 && !file.IsDir) { file.HasData = true; const CXmlItem &dataItem = item.SubItems[dataIndex]; if (!ParseUInt64(dataItem, "size", file.Size)) return false; if (!ParseUInt64(dataItem, "length", file.PackSize)) return false; if (!ParseUInt64(dataItem, "offset", file.Offset)) return false; file.Sha1IsDefined = ParseSha1(dataItem, "extracted-checksum", file.Sha1); // file.packSha1IsDefined = ParseSha1(dataItem, "archived-checksum", file.packSha1); int encodingIndex = dataItem.FindSubTag("encoding"); if (encodingIndex >= 0) { const CXmlItem &encodingItem = dataItem.SubItems[encodingIndex]; if (encodingItem.IsTag) { AString s = encodingItem.GetPropVal("style"); if (!s.IsEmpty()) { const AString appl = "application/"; if (s.IsPrefixedBy(appl)) { s.DeleteFrontal(appl.Len()); const AString xx = "x-"; if (s.IsPrefixedBy(xx)) { s.DeleteFrontal(xx.Len()); if (s == "gzip") s = METHOD_NAME_ZLIB; } } file.Method = s; } } } } file.CTime = ParseTime(item, "ctime"); file.MTime = ParseTime(item, "mtime"); file.ATime = ParseTime(item, "atime"); { const AString s = item.GetSubStringForTag("mode"); if (s[0] == '0') { const char *end; file.Mode = ConvertOctStringToUInt32(s, &end); file.ModeDefined = (*end == 0); } } file.User = item.GetSubStringForTag("user"); file.Group = item.GetSubStringForTag("group"); files.Add(file); } FOR_VECTOR (i, item.SubItems) if (!AddItem(item.SubItems[i], files, parent)) return false; return true; }