void CImageInfo::Parse(const CXmlItem &item) { ParseTime(item, CTimeDefined, CTime, "CREATIONTIME"); ParseTime(item, MTimeDefined, MTime, "LASTMODIFICATIONTIME"); NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name); // IndexDefined = ParseNumber32(item.GetPropertyValue("INDEX"), Index); }
IMP_IInArchive_Props IMP_IInArchive_ArcProps #define PARSE_NUM(_num_, _dest_) \ { const char *end; _dest_ = ConvertStringToUInt32(p, &end); \ if ((unsigned)(end - p) != _num_) return 0; p += _num_ + 1; } static bool ParseUInt64(const CXmlItem &item, const char *name, UInt64 &res) { const AString s = item.GetSubStringForTag(name); if (s.IsEmpty()) return false; const char *end; res = ConvertStringToUInt64(s, &end); return *end == 0; }
static UInt64 ParseTime(const CXmlItem &item, const char *name) { AString s = item.GetSubStringForTag(name); if (s.Length() < 20) return 0; const char *p = s; if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || p[13] != ':' || p[16] != ':' || p[19] != 'Z') return 0; UInt32 year, month, day, hour, min, sec; if (!ParseNumber(p, 4, year )) return 0; if (!ParseNumber(p + 5, 2, month)) return 0; if (!ParseNumber(p + 8, 2, day )) return 0; if (!ParseNumber(p + 11, 2, hour )) return 0; if (!ParseNumber(p + 14, 2, min )) return 0; if (!ParseNumber(p + 17, 2, sec )) return 0; UInt64 numSecs; if (!NWindows::NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) return 0; return numSecs * 10000000; }
static UInt64 ParseTime(const CXmlItem &item, const char *name) { const AString s = item.GetSubStringForTag(name); if (s.Len() < 20) return 0; const char *p = s; if (p[ 4] != '-' || p[ 7] != '-' || p[10] != 'T' || p[13] != ':' || p[16] != ':' || p[19] != 'Z') return 0; UInt32 year, month, day, hour, min, sec; PARSE_NUM(4, year) PARSE_NUM(2, month) PARSE_NUM(2, day) PARSE_NUM(2, hour) PARSE_NUM(2, min) PARSE_NUM(2, sec) UInt64 numSecs; if (!NTime::GetSecondsSince1601(year, month, day, hour, min, sec, numSecs)) return 0; return numSecs * 10000000; }
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; }