MCPcopy Create free account
hub / github.com/apache/orc / parseZoneFile

Method parseZoneFile

c++/src/Timezone.cc:869–946  ·  view source on GitHub ↗

* Parse the zone file to get the bits we need. * There are two versions of the timezone file: * * Version 1(version = 0x00): * Magic(version) * Header * TransitionTimes(4 byte) * TransitionRules * Rules * LeapSeconds(4 byte) * IsStd * IsGmt * * Version2: * Version1(0x32) = a version 1 copy of the data for old clients * Magic(0x32)

Source from the content-addressed store, hash-verified

867 * FutureString
868 */
869 void TimezoneImpl::parseZoneFile(const unsigned char* ptr, uint64_t sectionOffset,
870 uint64_t fileLength, const VersionParser& versionParser) {
871 const uint64_t magicOffset = sectionOffset + 0;
872 const uint64_t headerOffset = magicOffset + 20;
873
874 // check for validity before we start parsing
875 if (fileLength < headerOffset + 6 * 4 ||
876 strncmp(reinterpret_cast<const char*>(ptr) + magicOffset, "TZif", 4) != 0) {
877 std::stringstream buffer;
878 buffer << "non-tzfile " << filename_;
879 throw TimezoneError(buffer.str());
880 }
881
882 const uint64_t isGmtCount = decode32(ptr + headerOffset + 0);
883 const uint64_t isStdCount = decode32(ptr + headerOffset + 4);
884 const uint64_t leapCount = decode32(ptr + headerOffset + 8);
885 const uint64_t timeCount = decode32(ptr + headerOffset + 12);
886 const uint64_t variantCount = decode32(ptr + headerOffset + 16);
887 const uint64_t nameCount = decode32(ptr + headerOffset + 20);
888
889 const uint64_t timeOffset = headerOffset + 24;
890 const uint64_t timeVariantOffset = timeOffset + versionParser.getTimeSize() * timeCount;
891 const uint64_t variantOffset = timeVariantOffset + timeCount;
892 const uint64_t nameOffset = variantOffset + variantCount * 6;
893 const uint64_t sectionLength = nameOffset + nameCount +
894 (versionParser.getTimeSize() + 4) * leapCount + isGmtCount +
895 isStdCount;
896
897 if (sectionLength > fileLength) {
898 std::stringstream buffer;
899 buffer << "tzfile too short " << filename_ << " needs " << sectionLength << " and has "
900 << fileLength;
901 throw TimezoneError(buffer.str());
902 }
903
904 // if it is version 2, skip over the old layout and read the new one.
905 if (sectionOffset == 0 && ptr[magicOffset + 4] != 0) {
906 parseZoneFile(ptr, sectionLength, fileLength, Version2Parser());
907 return;
908 }
909 version_ = versionParser.getVersion();
910 variants_.resize(variantCount);
911 transitions_.resize(timeCount);
912 currentVariant_.resize(timeCount);
913 parseTimeVariants(ptr, variantOffset, variantCount, nameOffset, nameCount);
914 bool foundAncient = false;
915 for (uint64_t t = 0; t < timeCount; ++t) {
916 transitions_[t] = versionParser.parseTime(ptr + timeOffset + t * versionParser.getTimeSize());
917 currentVariant_[t] = ptr[timeVariantOffset + t];
918 if (currentVariant_[t] >= variantCount) {
919 std::stringstream buffer;
920 buffer << "tzfile rule out of range " << filename_ << " references rule "
921 << currentVariant_[t] << " of " << variantCount;
922 throw TimezoneError(buffer.str());
923 }
924 // find the oldest standard time and use that as the ancient value
925 if (!foundAncient && !variants_[currentVariant_[t]].isDst) {
926 foundAncient = true;

Callers

nothing calls this directly

Calls 10

TimezoneErrorClass · 0.85
decode32Function · 0.85
Version2ParserClass · 0.85
parseFutureRuleFunction · 0.85
isDefinedMethod · 0.80
getVersionMethod · 0.65
getTimeSizeMethod · 0.45
resizeMethod · 0.45
parseTimeMethod · 0.45
parseFutureStringMethod · 0.45

Tested by

no test coverage detected