summaryrefslogtreecommitdiff
path: root/src/main/include/log4cxx/helpers/cacheddateformat.h
blob: 527ed25670f6933dcc91387890f0a15ff166c0e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LOG4CXX_HELPERS_CACHED_DATE_FORMAT_H
#define _LOG4CXX_HELPERS_CACHED_DATE_FORMAT_H

#include <log4cxx/helpers/dateformat.h>

namespace log4cxx
{
        namespace pattern
        {
          class LOG4CXX_EXPORT CachedDateFormat : public log4cxx::helpers::DateFormat {
          public:
              enum {
                /*
                 *  Constant used to represent that there was no change
                 *  observed when changing the millisecond count.
                 */
                 NO_MILLISECONDS = -2,
                 /*
                  *  Constant used to represent that there was an
                  *  observed change, but was an expected change.
                  */
                 UNRECOGNIZED_MILLISECONDS = -1
              };

          private:
             /**
              *  Supported digit set.  If the wrapped DateFormat uses
              *  a different unit set, the millisecond pattern
              *  will not be recognized and duplicate requests
              *  will use the cache.
              */
               static const logchar digits[];

              enum {
               /**
                *  First magic number used to detect the millisecond position.
                */
               magic1 = 654000,
               /**
                *  Second magic number used to detect the millisecond position.
                */
               magic2 = 987000
              };

              /**
               *  Expected representation of first magic number.
               */
              static const logchar magicString1[];


              /**
               *  Expected representation of second magic number.
               */
              static const logchar magicString2[];


              /**
               *  Expected representation of 0 milliseconds.
               */
             static const logchar zeroString[];

            /**
             *   Wrapped formatter.
             */
            log4cxx::helpers::DateFormatPtr formatter;

            /**
             *  Index of initial digit of millisecond pattern or
             *   UNRECOGNIZED_MILLISECONDS or NO_MILLISECONDS.
             */
            mutable int millisecondStart;

            /**
             *  Integral second preceding the previous convered Date.
             */
            mutable log4cxx_time_t slotBegin;


            /**
             *  Cache of previous conversion.
             */
            mutable LogString cache;


            /**
             *  Maximum validity period for the cache.
             *  Typically 1, use cache for duplicate requests only, or
             *  1000000, use cache for requests within the same integral second.
             */
            const int expiration;

            /**
             *  Date requested in previous conversion.
             */
            mutable log4cxx_time_t previousTime;

       public:
          /**
           *  Creates a new CachedDateFormat object.
           *  @param dateFormat Date format, may not be null.
           *  @param expiration maximum cached range in microseconds.
           *    If the dateFormat is known to be incompatible with the
           *      caching algorithm, use a value of 0 to totally disable
           *      caching or 1 to only use cache for duplicate requests.
           */
            CachedDateFormat(const log4cxx::helpers::DateFormatPtr& dateFormat, int expiration);

            /**
             * Finds start of millisecond field in formatted time.
             * @param time long time, must be integral number of seconds
             * @param formatted String corresponding formatted string
             * @param formatter DateFormat date format
             * @param pool pool.
             * @return int position in string of first digit of milliseconds,
             *    -1 indicates no millisecond field, -2 indicates unrecognized
             *    field (likely RelativeTimeDateFormat)
             */
            static int findMillisecondStart(
              log4cxx_time_t time, const LogString& formatted,
                  const log4cxx::helpers::DateFormatPtr& formatter,
                  log4cxx::helpers::Pool& pool);

            /**
             * Formats a Date into a date/time string.
             *
             *  @param date the date to format.
             *  @param sbuf the string buffer to write to.
             *  @param p memory pool.
             */
               virtual void format(LogString &sbuf,
                   log4cxx_time_t date,
                   log4cxx::helpers::Pool& p) const;

           private:
               /**
                *   Formats a count of milliseconds (0-999) into a numeric representation.
                *   @param millis Millisecond coun between 0 and 999.
                *   @buf String buffer, may not be null.
                *   @offset Starting position in buffer, the length of the
                *       buffer must be at least offset + 3.
                */
                static void millisecondFormat(int millis,
                    LogString& buf,
                    int offset);


           public:
               /**
                * Set timezone.
                *
                * @remarks Setting the timezone using getCalendar().setTimeZone()
                * will likely cause caching to misbehave.
                * @param zone TimeZone new timezone
                */
               virtual void setTimeZone(const log4cxx::helpers::TimeZonePtr& zone);

                /**
                * Format an integer consistent with the format method.
                * @param s string to which the numeric string is appended.
                * @param n integer value.
                * @param p memory pool used during formatting.
                */
               virtual void numberFormat(LogString& s,
                                         int n,
                                         log4cxx::helpers::Pool& p) const;

              /**
               * Gets maximum cache validity for the specified SimpleDateTime
               *    conversion pattern.
               *  @param pattern conversion pattern, may not be null.
               *  @returns Duration in microseconds from an integral second
               *      that the cache will return consistent results.
               */
               static int getMaximumCacheValidity(const LogString& pattern);

          private:
               CachedDateFormat(const CachedDateFormat&);
               CachedDateFormat& operator=(const CachedDateFormat&);

               /**
               * Tests if two string regions are equal.
               * @param target target string.
               * @param toffset character position in target to start comparison.
               * @param other other string.
               * @param ooffset character position in other to start comparison.
               * @param len length of region.
               * @return true if regions are equal.
               */
               static bool regionMatches(
                   const LogString& target,
                   size_t toffset,
                   const LogString& other,
                   size_t ooffset,
                   size_t len);

          };



        }  // namespace helpers
} // namespace log4cxx

#endif // _LOG4CXX_HELPERS_SIMPLE_DATE_FORMAT_H