xref: /haiku/src/add-ons/kernel/file_systems/udf/Utils.cpp (revision d2fe364ca9380aeefaaedc2275f978992bb7900a)
1 //----------------------------------------------------------------------
2 //  This software is part of the OpenBeOS distribution and is covered
3 //  by the OpenBeOS license.
4 //
5 //  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //---------------------------------------------------------------------
7 
8 /*! \file Utils.cpp
9 
10 	Miscellaneous Udf utility functions.
11 */
12 
13 #include "Utils.h"
14 
15 extern "C" {
16 	#ifndef _IMPEXP_KERNEL
17 	#	define _IMPEXP_KERNEL
18 	#endif
19 
20 	extern int32 timezone_offset;
21 }
22 
23 
24 namespace Udf {
25 
26 udf_long_address
27 to_long_address(vnode_id id, uint32 length)
28 {
29 	DEBUG_INIT_ETC(CF_PUBLIC | CF_HELPER, NULL, ("vnode_id: %Ld, length: %ld", id, length));
30 	udf_long_address result;
31 	result.set_block((id >> 16) & 0xffffffff);
32 	result.set_partition(id & 0xffff);
33 	result.set_length(length);
34 	DUMP(result);
35 	return result;
36 }
37 
38 vnode_id
39 to_vnode_id(udf_long_address address)
40 {
41 	return (address.block() << 16) | (address.partition());
42 }
43 
44 time_t
45 make_time(udf_timestamp &timestamp)
46 {
47 	DEBUG_INIT_ETC(CF_HELPER | CF_HIGH_VOLUME, NULL, ("timestamp: (tnt: 0x%x, type: %d, timezone: %d = 0x%x, year: %d, "
48 	           "month: %d, day: %d, hour: %d, minute: %d, second: %d)", timestamp.type_and_timezone(),
49 	           timestamp.type(), timestamp.timezone(),
50 	            timestamp.timezone(),timestamp.year(),
51 	           timestamp.month(), timestamp.day(), timestamp.hour(), timestamp.minute(), timestamp.second()));
52 
53 	time_t result = 0;
54 
55 	if (timestamp.year() >= 1970) {
56 		const int monthLengths[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
57 
58 		int year = timestamp.year();
59 		int month = timestamp.month();
60 		int day = timestamp.day();
61 		int hour = timestamp.hour();
62 		int minute = timestamp.minute();
63 		int second = timestamp.second();
64 
65 		// Range check the timezone offset, then round it down
66 		// to the nearest hour, since no one I know treats timezones
67 		// with a per-minute granularity, and none of the other OSes
68 		// I've looked at appear to either.
69 		int timezone_offset = timestamp.timezone();
70 		if (-1440 > timezone_offset || timezone_offset > 1440)
71 			timezone_offset = 0;
72 		timezone_offset -= timezone_offset % 60;
73 
74 		int previousLeapYears = (year - 1968) / 4;
75 		bool isLeapYear = (year - 1968) % 4 == 0;
76 		if (isLeapYear)
77 			--previousLeapYears;
78 
79 		// Years to days
80 		result = (year - 1970) * 365 + previousLeapYears;
81 		// Months to days
82 		for (int i = 0; i < month-1; i++) {
83 			result += monthLengths[i];
84 		}
85 		if (month > 2 && isLeapYear)
86 			++result;
87 		// Days to hours
88 		result = (result + day - 1) * 24;
89 		// Hours to minutes
90 		result = (result + hour) * 60 + timezone_offset;
91 		// Minutes to seconds
92 		result = (result + minute) * 60 + second;
93 	}
94 
95 	return result;
96 }
97 
98 } // namespace Udf
99