pax_global_header00006660000000000000000000000064144541123130014510gustar00rootroot0000000000000052 comment=5c36cf64d9683c3b0a922360b903826e89d27780 ox-2.14.17/000077500000000000000000000000001445411231300123125ustar00rootroot00000000000000ox-2.14.17/.clang-format000066400000000000000000000106611445411231300146710ustar00rootroot00000000000000--- Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveMacros: false AlignConsecutiveAssignments: true AlignConsecutiveDeclarations: true AlignEscapedNewlines: Left AlignOperands: true AlignTrailingComments: true AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: InlineOnly AllowShortLambdasOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes BinPackArguments: false BinPackParameters: false BraceWrapping: AfterCaseLabel: false AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false AfterExternBlock: false BeforeCatch: false BeforeElse: false IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeInheritanceComma: false BreakInheritanceList: BeforeColon BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true ColumnLimit: 120 CommentPragmas: '^ IWYU pragma:' CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: true DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH IncludeBlocks: Regroup IncludeCategories: - Regex: '^' Priority: 2 SortPriority: 0 - Regex: '^<.*\.h>' Priority: 1 SortPriority: 0 - Regex: '^<.*' Priority: 2 SortPriority: 0 - Regex: '.*' Priority: 3 SortPriority: 0 IncludeIsMainRegex: '([-_](test|unittest))?$' IncludeIsMainSourceRegex: '' IndentCaseLabels: false IndentGotoLabels: true IndentPPDirectives: None IndentWidth: 4 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Never ObjCBlockIndentWidth: 4 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true PenaltyBreakAssignment: 2000 PenaltyBreakBeforeFirstCallParameter: 1 PenaltyBreakComment: 100 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 100 PenaltyReturnTypeOnItsOwnLine: 1 PointerAlignment: Right RawStringFormats: - Language: Cpp Delimiters: - cc - CC - cpp - Cpp - CPP - 'c++' - 'C++' CanonicalDelimiter: '' BasedOnStyle: google - Language: TextProto Delimiters: - pb - PB - proto - PROTO EnclosingFunctions: - EqualsProto - EquivToProto - PARSE_PARTIAL_TEXT_PROTO - PARSE_TEST_PROTO - PARSE_TEXT_PROTO - ParseTextOrDie - ParseTextProtoOrDie CanonicalDelimiter: '' BasedOnStyle: google ReflowComments: true SortIncludes: true SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: true SpaceBeforeAssignmentOperators: true SpaceBeforeCpp11BracedList: false SpaceBeforeCtorInitializerColon: true SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 2 SpacesInAngles: false SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false Standard: Auto StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION TabWidth: 8 UseCRLF: false UseTab: Never ... ox-2.14.17/.editorconfig000066400000000000000000000004331445411231300147670ustar00rootroot00000000000000# EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true # Unix-style newlines with a newline ending every file [*] end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = space indent_size = 2 trim_trailing_whitespace = true ox-2.14.17/.github/000077500000000000000000000000001445411231300136525ustar00rootroot00000000000000ox-2.14.17/.github/FUNDING.yml000066400000000000000000000000231445411231300154620ustar00rootroot00000000000000 github: [ohler55] ox-2.14.17/.github/dependabot.yml000066400000000000000000000002231445411231300164770ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: github-actions directory: '/' schedule: interval: weekly open-pull-requests-limit: 99 ox-2.14.17/.github/workflows/000077500000000000000000000000001445411231300157075ustar00rootroot00000000000000ox-2.14.17/.github/workflows/CI.yml000066400000000000000000000014111445411231300167220ustar00rootroot00000000000000name: CI on: push: branches: - develop - master pull_request: jobs: Build: strategy: fail-fast: true matrix: # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' ruby: - head - '3.2' - '3.1' - '3.0' - '2.7' os: - ubuntu - macos - windows runs-on: ${{ matrix.os }}-latest continue-on-error: ${{ matrix.ruby == '3.0' || matrix.ruby == 'head'}} name: Ruby ${{ matrix.ruby }} (${{ matrix.os }}) steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - run: bundle exec rake ox-2.14.17/.github/workflows/clang-format.yml000066400000000000000000000011151445411231300210020ustar00rootroot00000000000000name: clang-format Check on: push: branches: - develop - master paths: - ".clang-format" - ".github/workflows/clang-format.yml" - "**/*.c" - "**/*.h" pull_request: paths: - ".clang-format" - ".github/workflows/clang-format.yml" - "**/*.c" - "**/*.h" jobs: formatting-check: name: Formatting Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Run clang-format style check uses: jidicula/clang-format-action@v4.11.0 with: clang-format-version: 16 ox-2.14.17/.github/workflows/rubocop.yml000066400000000000000000000013411445411231300201020ustar00rootroot00000000000000name: Rubocop Check on: push: branches: - develop - master paths: - ".rubocop*.yml" - ".github/workflows/rubocop.yml" - "**/*.rb" pull_request: paths: - ".rubocop*.yml" - ".github/workflows/rubocop.yml" - "**/*.rb" jobs: formatting-check: name: Formatting Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: "2.7" - name: Install rubocop run: gem install rubocop --no-doc - name: Set-up RuboCop Problem Matcher uses: r7kamura/rubocop-problem-matchers-action@v1 - name: Run rubocop run: rubocop ox-2.14.17/.gitignore000066400000000000000000000002331445411231300143000ustar00rootroot00000000000000ox-*.gem .DS_Store \#*\# .\#* *~ *.o *.so Makefile *.bundle .rbenv-version .ruby-version *.rbc .rbx .yardoc doc Gemfile.lock test/create_file_test.xml tmp ox-2.14.17/.rubocop.yml000066400000000000000000000007501445411231300145660ustar00rootroot00000000000000inherit_from: .rubocop_todo.yml AllCops: TargetRubyVersion: 2.7 NewCops: enable Naming/MethodName: EnforcedStyle: snake_case Exclude: - 'test/tests.rb' # test_IO doesn't match Style/FormatStringToken: EnforcedStyle: unannotated Style/HashSyntax: EnforcedStyle: ruby19_no_mixed_keys Style/QuotedSymbols: EnforcedStyle: double_quotes Style/RaiseArgs: EnforcedStyle: compact Style/SymbolArray: EnforcedStyle: brackets Style/WordArray: EnforcedStyle: brackets ox-2.14.17/.rubocop_todo.yml000066400000000000000000000506671445411231300156270ustar00rootroot00000000000000# This configuration was generated by # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit` # on 2023-03-02 04:53:03 UTC using RuboCop version 1.47.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. # Offense count: 26 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: space, no_space Layout/SpaceAroundEqualsInParameterDefault: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/document.rb' - 'lib/ox/element.rb' - 'test/ox/change.rb' - 'test/ox/doc.rb' - 'test/ox/oval.rb' - 'test/ox/rect.rb' - 'test/ox/shape.rb' - 'test/ox/text.rb' - 'test/perf_mars.rb' - 'test/sample.rb' - 'test/sample/change.rb' - 'test/sample/doc.rb' - 'test/sample/oval.rb' - 'test/sample/rect.rb' - 'test/sample/shape.rb' - 'test/sample/text.rb' - 'test/tests.rb' # Offense count: 10 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. # SupportedStylesForExponentOperator: space, no_space Layout/SpaceAroundOperators: Exclude: - 'contrib/xbuilder_test.rb' - 'lib/ox/element.rb' - 'test/perf_mars.rb' - 'test/sax/sax_test.rb' - 'test/tests.rb' # Offense count: 4 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space # SupportedStylesForEmptyBraces: space, no_space Layout/SpaceInsideBlockBraces: Exclude: - 'contrib/xbuilder.rb' - 'test/perf.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' # Offense count: 12 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: space, compact, no_space Layout/SpaceInsideParens: Exclude: - 'test/tests.rb' # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Exclude: - 'examples/sax_ractor.rb' # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). Lint/BooleanSymbol: Exclude: - 'test/parse_cmp.rb' # Offense count: 4 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: Exclude: - 'test/perf.rb' - 'test/tests.rb' # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowComments. Lint/EmptyConditionalBody: Exclude: - 'test/perf.rb' # Offense count: 1 Lint/LiteralAsCondition: Exclude: - 'test/sample/file.rb' # Offense count: 1 Lint/MissingSuper: Exclude: - 'test/perf_sax.rb' # Offense count: 18 Lint/RescueException: Exclude: - 'test/perf.rb' - 'test/perf_gen.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' # Offense count: 2 Lint/ShadowingOuterLocalVariable: Exclude: - 'test/perf_mars.rb' # Offense count: 11 # Configuration parameters: AllowComments, AllowNil. Lint/SuppressedException: Exclude: - 'test/perf_gen.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/weather/perf_weather.rb' # Offense count: 2 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: Exclude: - 'lib/ox/element.rb' - 'test/perf.rb' # Offense count: 14 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. Lint/UnusedMethodArgument: Exclude: - 'contrib/sax_benchmark.rb' - 'examples/sax_ractor.rb' - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'lib/ox/hasattrs.rb' - 'test/perf_sax.rb' - 'test/sax/handlers.rb' - 'test/weather/wlxsax.rb' - 'test/weather/wnosax.rb' - 'test/weather/wsax.rb' # Offense count: 24 Lint/UselessAssignment: Exclude: - 'test/cache8_test.rb' - 'test/cache_test.rb' - 'test/obj_sample.rb' - 'test/parse_cmp.rb' - 'test/perf_gen.rb' - 'test/perf_mars.rb' - 'test/perf_sax.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' # Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). Lint/UselessMethodDefinition: Exclude: - 'lib/ox/cdata.rb' - 'lib/ox/comment.rb' - 'lib/ox/doctype.rb' - 'lib/ox/raw.rb' - 'test/sax/handlers.rb' # Offense count: 35 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max. Metrics/AbcSize: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'test/ox/file.rb' - 'test/parse_cmp.rb' - 'test/perf.rb' - 'test/sample.rb' - 'test/sample/file.rb' - 'test/sax/sax_test.rb' - 'test/tests.rb' - 'test/weather/wlx.rb' - 'test/weather/wno.rb' - 'test/weather/wox.rb' # Offense count: 4 # Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns. # AllowedMethods: refine Metrics/BlockLength: Exclude: - '**/*.gemspec' - 'test/parse_cmp.rb' - 'test/perf_gen.rb' - 'test/tests.rb' # Offense count: 10 # Configuration parameters: CountBlocks, Max. Metrics/BlockNesting: Exclude: - 'lib/ox/element.rb' # Offense count: 6 # Configuration parameters: CountComments, Max, CountAsOne. Metrics/ClassLength: Exclude: - 'lib/ox/element.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' # Offense count: 13 # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/CyclomaticComplexity: Exclude: - 'contrib/xbuilder.rb' - 'lib/ox/element.rb' - 'test/ox/file.rb' - 'test/parse_cmp.rb' - 'test/perf.rb' - 'test/sample/file.rb' - 'test/weather/wlx.rb' - 'test/weather/wno.rb' # Offense count: 112 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 76 # Offense count: 4 # Configuration parameters: Max, CountKeywordArgs, MaxOptionalParameters. Metrics/ParameterLists: Exclude: - 'test/ox/line.rb' - 'test/ox/text.rb' - 'test/sample/line.rb' - 'test/sample/text.rb' # Offense count: 11 # Configuration parameters: AllowedMethods, AllowedPatterns, Max. Metrics/PerceivedComplexity: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'test/ox/file.rb' - 'test/parse_cmp.rb' - 'test/perf.rb' - 'test/sample/file.rb' - 'test/weather/wno.rb' # Offense count: 25 # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to Naming/MethodParameterName: Exclude: - 'examples/obj.rb' - 'lib/ox/bag.rb' - 'test/obj_sample.rb' - 'test/ox/dir.rb' - 'test/ox/line.rb' - 'test/perf.rb' - 'test/perf_mars.rb' - 'test/sample/dir.rb' - 'test/sample/line.rb' - 'test/sax/smart_test.rb' - 'test/weather/wsax.rb' # Offense count: 1 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns. # SupportedStyles: snake_case, normalcase, non_integer # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64 Naming/VariableNumber: Exclude: - 'test/sax/smart_test.rb' # Offense count: 3 Security/MarshalLoad: Exclude: - 'test/perf_mars.rb' - 'test/perf_obj.rb' # Offense count: 34 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: separated, grouped Style/AccessorGrouping: Exclude: - 'test/ox/change.rb' - 'test/ox/doc.rb' - 'test/ox/line.rb' - 'test/ox/shape.rb' - 'test/ox/text.rb' - 'test/perf.rb' - 'test/sample/change.rb' - 'test/sample/doc.rb' - 'test/sample/line.rb' - 'test/sample/shape.rb' - 'test/sample/text.rb' # Offense count: 22 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: always, conditionals Style/AndOr: Exclude: - 'examples/sax_ractor.rb' - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'lib/ox/hasattrs.rb' - 'lib/ox/node.rb' - 'test/parse_cmp.rb' - 'test/tests.rb' # Offense count: 2 # This cop supports unsafe autocorrection (--autocorrect-all). Style/CaseLikeIf: Exclude: - 'lib/ox/element.rb' - 'test/parse_cmp.rb' # Offense count: 2 Style/CombinableLoops: Exclude: - 'lib/ox/element.rb' # Offense count: 105 # This cop supports unsafe autocorrection (--autocorrect-all). Style/CommentedKeyword: Exclude: - 'examples/sax_ractor.rb' - 'lib/ox/bag.rb' - 'lib/ox/cdata.rb' - 'lib/ox/comment.rb' - 'lib/ox/doctype.rb' - 'lib/ox/document.rb' - 'lib/ox/element.rb' - 'lib/ox/error.rb' - 'lib/ox/hasattrs.rb' - 'lib/ox/instruct.rb' - 'lib/ox/node.rb' - 'lib/ox/raw.rb' - 'lib/ox/sax.rb' - 'test/obj_sample.rb' - 'test/ox/change.rb' - 'test/ox/dir.rb' - 'test/ox/doc.rb' - 'test/ox/file.rb' - 'test/ox/group.rb' - 'test/ox/hasprops.rb' - 'test/ox/layer.rb' - 'test/ox/line.rb' - 'test/ox/oval.rb' - 'test/ox/rect.rb' - 'test/ox/shape.rb' - 'test/ox/text.rb' - 'test/perf.rb' - 'test/sample/change.rb' - 'test/sample/dir.rb' - 'test/sample/doc.rb' - 'test/sample/file.rb' - 'test/sample/group.rb' - 'test/sample/hasprops.rb' - 'test/sample/layer.rb' - 'test/sample/line.rb' - 'test/sample/oval.rb' - 'test/sample/rect.rb' - 'test/sample/shape.rb' - 'test/sample/text.rb' - 'test/weather/wlx.rb' - 'test/weather/wlxsax.rb' - 'test/weather/wno.rb' - 'test/weather/wnosax.rb' - 'test/weather/wox.rb' - 'test/weather/wsax.rb' # Offense count: 12 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: Exclude: - 'contrib/sax_benchmark.rb' - 'ext/ox/extconf.rb' - 'lib/ox/element.rb' - 'test/files.rb' - 'test/sample/file.rb' - 'test/weather/wlxsax.rb' - 'test/weather/wnosax.rb' - 'test/weather/wsax.rb' # Offense count: 4 # Configuration parameters: AllowedConstants. Style/Documentation: Exclude: - 'spec/**/*' - 'test/**/*' - 'contrib/sax_benchmark.rb' - 'contrib/xbuilder.rb' - 'contrib/xbuilder_test.rb' # Offense count: 4 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedVars. Style/FetchEnvVar: Exclude: - 'test/ox/change.rb' - 'test/ox/doc.rb' - 'test/sample/change.rb' - 'test/sample/doc.rb' # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: each, for Style/For: Exclude: - 'contrib/xbuilder.rb' # Offense count: 76 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: always, always_true, never Style/FrozenStringLiteralComment: Exclude: - 'Gemfile' - 'contrib/sax_benchmark.rb' - 'contrib/xbuilder.rb' - 'contrib/xbuilder_test.rb' - 'examples/gen.rb' - 'examples/hashi.rb' - 'examples/obj.rb' - 'examples/sax_ractor.rb' - 'examples/saxy.rb' - 'examples/saxy_html.rb' - 'ext/ox/extconf.rb' - 'lib/ox.rb' - 'lib/ox/bag.rb' - 'lib/ox/cdata.rb' - 'lib/ox/comment.rb' - 'lib/ox/doctype.rb' - 'lib/ox/document.rb' - 'lib/ox/element.rb' - 'lib/ox/error.rb' - 'lib/ox/hasattrs.rb' - 'lib/ox/instruct.rb' - 'lib/ox/node.rb' - 'lib/ox/raw.rb' - 'lib/ox/sax.rb' - 'lib/ox/version.rb' - 'lib/ox/xmlrpc_adapter.rb' - 'ox.gemspec' - 'test/cache8_test.rb' - 'test/cache_test.rb' - 'test/files.rb' - 'test/gen_sample.rb' - 'test/obj_sample.rb' - 'test/ox/change.rb' - 'test/ox/dir.rb' - 'test/ox/doc.rb' - 'test/ox/file.rb' - 'test/ox/group.rb' - 'test/ox/hasprops.rb' - 'test/ox/layer.rb' - 'test/ox/line.rb' - 'test/ox/oval.rb' - 'test/ox/rect.rb' - 'test/ox/shape.rb' - 'test/ox/text.rb' - 'test/parse_cmp.rb' - 'test/perf.rb' - 'test/perf_gen.rb' - 'test/perf_mars.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/sample.rb' - 'test/sample/change.rb' - 'test/sample/dir.rb' - 'test/sample/doc.rb' - 'test/sample/file.rb' - 'test/sample/group.rb' - 'test/sample/hasprops.rb' - 'test/sample/layer.rb' - 'test/sample/line.rb' - 'test/sample/oval.rb' - 'test/sample/rect.rb' - 'test/sample/shape.rb' - 'test/sample/text.rb' - 'test/sax/handlers.rb' - 'test/sax/helpers.rb' - 'test/sax/sax_check.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' - 'test/weather/wlx.rb' - 'test/weather/wlxsax.rb' - 'test/weather/wno.rb' - 'test/weather/wnosax.rb' - 'test/weather/wox.rb' - 'test/weather/wsax.rb' # Offense count: 400 # Configuration parameters: AllowedVariables. Style/GlobalVars: Exclude: - 'ext/ox/extconf.rb' - 'test/parse_cmp.rb' - 'test/perf_gen.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/sax/sax_test.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' # Offense count: 3 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle. # SupportedStyles: line_count_dependent, lambda, literal Style/Lambda: Exclude: - 'test/sax/smart_test.rb' - 'test/tests.rb' # Offense count: 3 Style/MissingRespondToMissing: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'lib/ox/hasattrs.rb' # Offense count: 1 Style/MultilineBlockChain: Exclude: - 'examples/sax_ractor.rb' # Offense count: 4 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: literals, strict Style/MutableConstant: Exclude: - 'examples/saxy_html.rb' - 'lib/ox/version.rb' - 'test/sax/smart_test.rb' # Offense count: 18 # This cop supports safe autocorrection (--autocorrect). Style/NegatedIfElseCondition: Exclude: - 'test/ox/file.rb' - 'test/sample/file.rb' # Offense count: 1 # Configuration parameters: EnforcedStyle. # SupportedStyles: allow_single_line, disallow Style/NumberedParameters: Exclude: - 'examples/sax_ractor.rb' # Offense count: 1 # Configuration parameters: Max. Style/NumberedParametersLimit: Exclude: - 'examples/sax_ractor.rb' # Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns. # SupportedStyles: predicate, comparison Style/NumericPredicate: Exclude: - 'spec/**/*' - 'examples/sax_ractor.rb' - 'lib/ox/element.rb' - 'test/perf_mars.rb' # Offense count: 3 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: Exclude: - 'lib/ox/element.rb' - 'test/tests.rb' # Offense count: 10 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions. Style/ParenthesesAroundCondition: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'lib/ox/node.rb' - 'test/perf_obj.rb' - 'test/tests.rb' # Offense count: 192 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: Exclude: - 'contrib/sax_benchmark.rb' - 'examples/gen.rb' - 'examples/hashi.rb' - 'examples/saxy.rb' - 'test/parse_cmp.rb' - 'test/perf_sax.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' # Offense count: 8 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: short, verbose Style/PreferredHashMethods: Exclude: - 'lib/ox/element.rb' - 'lib/ox/hasattrs.rb' # Offense count: 8 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Methods. Style/RedundantArgument: Exclude: - 'ext/ox/extconf.rb' - 'test/ox/file.rb' - 'test/sample/file.rb' - 'test/tests.rb' # Offense count: 5 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowComments. Style/RedundantInitialize: Exclude: - 'lib/ox/cdata.rb' - 'lib/ox/comment.rb' - 'lib/ox/doctype.rb' - 'lib/ox/raw.rb' - 'test/sax/handlers.rb' # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. # AllowedMethods: present?, blank?, presence, try, try! Style/SafeNavigation: Exclude: - 'test/perf.rb' # Offense count: 24 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowAsExpressionSeparator. Style/Semicolon: Exclude: - 'test/parse_cmp.rb' - 'test/perf_gen.rb' - 'test/perf_mars.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' # Offense count: 11 # This cop supports unsafe autocorrection (--autocorrect-all). Style/SlicingWithRange: Exclude: - 'lib/ox/element.rb' - 'test/weather/wox.rb' # Offense count: 62 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: RequireEnglish, EnforcedStyle. # SupportedStyles: use_perl_names, use_english_names, use_builtin_english_names Style/SpecialGlobalVars: Exclude: - 'contrib/xbuilder_test.rb' - 'test/cache8_test.rb' - 'test/cache_test.rb' - 'test/files.rb' - 'test/parse_cmp.rb' - 'test/perf_gen.rb' - 'test/perf_mars.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/sample.rb' - 'test/sax/sax_check.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' - 'test/weather/perf_weather.rb' # Offense count: 4 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: Mode. Style/StringConcatenation: Exclude: - 'ext/ox/extconf.rb' - 'lib/ox/bag.rb' - 'test/tests.rb' # Offense count: 21 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments. # AllowedMethods: define_method Style/SymbolProc: Exclude: - 'lib/ox/bag.rb' - 'lib/ox/element.rb' - 'test/perf.rb' - 'test/tests.rb' # Offense count: 1 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyleForMultiline. # SupportedStylesForMultiline: comma, consistent_comma, no_comma Style/TrailingCommaInArguments: Exclude: - 'examples/sax_ractor.rb' # Offense count: 71 # This cop supports unsafe autocorrection (--autocorrect-all). # Configuration parameters: EnforcedStyle. # SupportedStyles: forbid_for_all_comparison_operators, forbid_for_equality_operators_only, require_for_all_comparison_operators, require_for_equality_operators_only Style/YodaCondition: Exclude: - 'examples/saxy_html.rb' - 'ext/ox/extconf.rb' - 'lib/ox/element.rb' - 'test/ox/file.rb' - 'test/parse_cmp.rb' - 'test/perf_mars.rb' - 'test/sample/file.rb' - 'test/tests.rb' - 'test/weather/wlx.rb' - 'test/weather/wlxsax.rb' - 'test/weather/wno.rb' - 'test/weather/wnosax.rb' - 'test/weather/wsax.rb' # Offense count: 1 # This cop supports unsafe autocorrection (--autocorrect-all). Style/ZeroLengthPredicate: Exclude: - 'examples/sax_ractor.rb' # Offense count: 28 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns. # URISchemes: http, https Layout/LineLength: Exclude: - 'examples/sax_ractor.rb' - 'lib/ox/element.rb' - 'test/perf_gen.rb' - 'test/perf_mars.rb' - 'test/perf_obj.rb' - 'test/perf_sax.rb' - 'test/sax/sax_test.rb' - 'test/sax/smart_test.rb' - 'test/tests.rb' ox-2.14.17/CHANGELOG.md000066400000000000000000000434551445411231300141360ustar00rootroot00000000000000# Changelog All changes to the Ox gem are documented here. Releases follow semantic versioning. ## [2.14.17] - 2023-07-14 ### Fixed - The sax parser in html mode now allows unquoted attribute values with complaints. ## [2.14.16] - 2023-04-11 ### Fixed - Window issue with strndup fixed thats to alexanderfast. ## [2.14.15] - 2023-04-10 ### Fixed - Fixed free on moved pointer. ## [2.14.14] - 2023-01-26 ### Fixed - Change free to xfree on ruby alloced memory. ## [2.14.13] - 2023-01-16 ### Fixed - Fixed the intern cache to handle symbol memory changes. ## [2.14.12] - 2022-12-27 ### Fixed - Updated to support Ruby 3.2. ## [2.14.11] - 2022-03-31 ### Fixed - Missing attribute value no longer crashes with the SAX parser. ## [2.14.10] - 2022-03-10 ### Fixed - Writing strings over 16K to a file with builder no longer causes a crash. ## [2.14.9] - 2022-02-11 ### Fixed - Fixed the `\r` replacement with `\n` with the SAX parser according to https://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends. ## [2.14.8] - 2022-02-09 ### Fixed - Renamed internal functions to avoid linking issues where Oj and Ox function names collided. ## [2.14.7] - 2022-02-03 ### Fixed - All classes and symbols are now registered to avoid issues with GC compaction movement. - Parsing of any size processing instruction is now allowed. There is no 1024 limit. - Fixed the `\r` replacement with `\n` according to https://www.w3.org/TR/2008/REC-xml-20081126/#sec-line-ends. ### Changed - Symbol and string caching changed but should have no impact on use other than being slightly faster and handles large numbers of cached items more efficiently. ## [2.14.6] - 2021-11-03 ### Fixed - Closing tags in builder are now escapped correctly thanks to ezekg. ## [2.14.5] - 2021-06-04 ### Fixed - Fixed RDoc for for Ox::Builder. ## [2.14.4] - 2021-03-19 ### Fixed - Really fixed code issue around HAVE_RB_ENC_ASSOCIATE. ## [2.14.3] - 2021-03-12 ### Fixed - Code issue around HAVE_RB_ENC_ASSOCIATE fixed. ## [2.14.2] - 2021-03-07 ### Fixed - Attribute keys for setting attributes no longer create seemily duplicates if symbol and string keys are mixed. ## [2.14.1] - 2021-01-11 ### Fixed - In Ruby 3.0 Range objects are frozen. This version allows Ranges to be created on load. ## [2.14.0] - 2020-12-15 ### Added - The `:with_cdata` option added for the hash_load() function. ## [2.13.4] - 2020-09-11 ### Fixed - Fixed one crash that occurred when a corrupted object encoded string was provided. ## [2.13.3] - 2020-09-03 ### Changed - mkmf have macros used instead of ad-hoc determinations. ## [2.13.2] - 2020-02-05 Skip and missed sequence ### Fixed - Add ' sequence. - `:skip_off` no longer misses spaces between elements. ## [2.13.1] - 2020-01-30 HTML Sequences ### Added - All HTML 4 sequence are now supported. ## [2.13.0] - 2020-01-25 HTML Escape Sequences ### Added - All HTML 4 escape sequences are now parsed. ## [2.12.1] - 2020-01-05 Ruby 2.7.0 ### Fixed - Updated for Ruby 2.7.0. More strict type checking. Function signature changes, and `Object#taint` deprecated. ## [2.12.0] - 2019-12-18 ### Added - Add `no_empty` option to not allow and use instead. ## [2.11.0] - 2019-06-14 ### Changed - Ox::SyntaxError replaces SyntaxError where such an exception would have previously been raised. ### Fixed - File offsets when using the SAX parser now use `off_t`. Setting `-D_FILE_OFFSET_BITS=64` in the Makefile may allow 32 bit systems to access files larger than 2^32 in size. This has not been tested. ## [2.10.1] - 2019-05-27 ### Fixed - Remove extra space from doctype dump. ## [2.10.0] - 2018-08-26 ### Fixed - `:element_key_mod` and `:attr_key_mod` options were added to allow keys to be modified when loading. ## [2.9.4] - 2018-07-16 ### Fixed - Fixed issue with malformed object mode input. ## [2.9.3] - 2018-06-12 ### Fixed - Handle `\0` in dumped strings better. - No `\n` added on dumped if indent is less than zero. ## [2.9.2] - 2018-04-16 ### Fixed - `locate` fixed to cover a missing condition with named child thanks to mberlanda. ### Added - `locate` supports attribute exists searches thanks to mberlanda. ## [2.9.1] - 2018-04-14 ### Fixed - `prepend_child` added by mberlanda. ## [2.9.0] - 2018-03-13 ### Added - New builder methods for building HTML. - Examples added. ## [2.8.4] - 2018-03-4 ### Fixed - Commented out debug statement. ## [2.8.3] - 2018-03-3 ### Fixed - Attribute values now escape < and > on dump. ## [2.8.2] - 2017-11-1 ### Fixed - Fixed bug with SAX parser that caused a crash with very long invalid instruction element. - Fixed SAX parse error with double elements. ## [2.8.1] - 2017-10-27 ### Fixed - Avoid crash with invalid XML passed to Ox.parse_obj(). ## [2.8.0] - 2017-09-22 ### Fixed - Added :skip_off mode to make sax callback on every none empty string even if there are not other non-whitespace characters present. ## [2.7.0] - 2017-08-18 ### Added - Two new load modes added, :hash and :hash_no_attrs. Both load an XML document to create a Hash populated with core Ruby objects. ### Fixed - Worked around Ruby API change for RSTRUCT_LEN so Ruby 2.4.2 does not crash. ## [2.6.0] - 2017-08-9 ### Added - The Element#each() method was added to allow iteration over Element nodes conditionally. - Element#locate() now supports a [@attr=value] specification. - An underscore character used in the easy API is now treated as a wild card for valid XML characters that are not valid for Ruby method names. ## [2.5.0] - 2017-05-4 ### Added - Added a :nest_ok option to SAX hints that will ignore the nested check on a tag to accomadate non-compliant HTML. ### Changed - Set the default for skip to be to skip white space. ## [2.4.13] - 2017-04-21 ### Fixed - Corrected Builder special character handling. ## [2.4.12] - 2017-04-11 ### Fixed - Fixed position in builder when encoding special characters. ## [2.4.11] - 2017-03-19 ### Fixed - Fixed SAX parser bug regarding upper case hints not matching. ## [2.4.10] - 2017-02-13 ### Fixed - Dump is now smarter about which characters to replace with &xxx; alternatives. ## [2.4.9] - 2017-01-25 ### Added - Added a SAX hint that allows comments to be treated like other elements. ## [2.4.8] - 2017-01-15 ### Changed - Tolerant mode now allows case-insensitve matches on elements during parsing. Smart mode in the SAX parser is also case insensitive. ## [2.4.7] - 2016-December-25 ### Fixed - After encountering a <> the SAX parser will continue parsing after reporting an error. ## [2.4.6] - 2016-11-28 ### Added - Added margin option to dump. ## [2.4.5] - 2016-09-11 ### Fixed - Thanks to GUI for fixing an infinite loop in Ox::Builder. ## [2.4.4] - 2016-08-9 ### Fixed - Builder element attributes with special characters are now encoded correctly. - A newline at end of an XML string is now controlled by the indent value. A value of-1 indicates no terminating newline character and an indentation of zero. ## [2.4.3] - 2016-06-26 ### Fixed - Fixed compiler warnings and errors. - Updated for Ruby 2.4.0. ## [2.4.2] - 2016-06-23 ### Fixed - Added methods to Ox::Builder to provide output position information. ## [2.4.1] - 2016-04-30 ### Added - Added overlay feature to give control over which elements generate callbacks with the SAX parser. - Element.locate now includes self if the path is relative and starts with a wildcard. ### Fixed - Made SAX smarter a little smarter or rather let it handle unquoted string with a / at the end. - Fixed bug with reporting errors of element names that are too long. ## [2.4.0] - 2016-04-14 ### Fixed - Added Ox::Builder that constructs an XML string or writes XML to a stream using builder methods. ## [2.3.0] - 2016-02-21 ### Added - Added Ox::Element.replace_text() method. - A invalid_replace option has been added. It will replace invalid XML character with a provided string. Strict effort now raises an exception if an invalid character is encountered on dump or load. ### Changed - Ox.load and Ox.parse now allow for a callback block to handle multiple top level entities in the input. - The Ox SAX parser now supports strings as input directly without and IO wrapper. ### Fixed - Ox::Element nodes variable is now always initialized to an empty Array. - Ox::Element attributes variable is now always initialized to an empty Hash. ## [2.2.4] - 2016-02-4 ### Fixed - Changed the code to allow compilation on older compilers. No change in functionality otherwise. ## [2.2.3] - 2015-December-31 ### Fixed - The convert_special option now applies to attributes as well as elements in the SAX parser. - The convert_special option now applies to the regualr parser as well as the SAX parser. - Updated to work correctly with Ruby 2.3.0. ## [2.2.2] - 2015-10-19 ### Fixed - Fixed problem with detecting invalid special character sequences. - Fixed bug that caused a crash when an <> was encountered with the SAX parser. ## [2.2.1] - 2015-07-30 ### Fixed - Added support to handle script elements in html. - Added support for position from start for the sax parser. ## [2.2.0] - 2015-04-20 ### Fixed - Added the SAX convert_special option to the default options. - Added the SAX smart option to the default options. - Other SAX options are now taken from the defaults if not specified. ## [2.1.8] - 2015-02-10 ### Fixed - Fixed a bug that caused all input to be read before parsing with the sax parser and an IO.pipe. ## [2.1.7] - 2015-01-31 ### Fixed - Empty elements such as are now called back with empty text. - Fixed GC problem that occurs with the new GC in Ruby 2.2 that garbage collects Symbols. ## [2.1.6] - 2014-December-31 ### Fixed - Update licenses. No other changes. ## [2.1.5] - 2014-December-30 ### Fixed - Fixed symbol intern problem with Ruby 2.2.0. Symbols are not dynamic unless rb_intern(). There does not seem to be a way to force symbols created with encoding to be pinned. ## [2.1.4] - 2014-December-5 ### Fixed - Fixed bug where the parser always started at the first position in a stringio instead of the current position. ## [2.1.3] - 2014-07-25 ### Fixed - Added check for @attributes being nil. Reported by and proposed fix by Elana. ## [2.1.2] - 2014-07-17 ### Fixed - Added skip option to parsing. This allows white space to be collapsed in two different ways. - Added respond_to? method for easy access method checking. ## [2.1.1] - 2014-02-12 ### Fixed - Worked around a module reset and clear that occurs on some Rubies. ## [2.1.0] - 2014-02-2 ### Fixed - Thanks to jfontan Ox now includes support for XMLRPC. ## [2.0.12] - 2013-05-21 ### Fixed - Fixed problem compiling with latest version of Rubinius. ## [2.0.11] - 2013-10-17 ### Fixed - Added support for BigDecimals in :object mode. ## [10.2.10] ### Fixed - Small fix to not create an empty element from a closed element when using locate(). - Fixed to keep objects from being garbages collected in Ruby 2.x. ## [2.0.9] - 2013-09-2 ### Fixed - Fixed bug that did not allow ISO-8859-1 characters and caused a crash. ## [2.0.8] - 2013-08-6 ### Fixed - Allow single quoted strings in all modes. ## [2.0.7] - 2013-08-4 ### Fixed - Fixed DOCTYPE parsing to handle nested '>' characters. ## [2.0.6] - 2013-07-23 ### Fixed - Fixed bug in special character decoding that chopped of text. - Limit depth on dump to 1000 to avoid core dump on circular references if the user does not specify circular. - Handles dumping non-string values for attributes correctly by converting the value to a string. ## [2.0.5] - 2013-07-5 ### Fixed - Better support for special character encoding with 1.8.7.- February 8, 2013 ## [2.0.4] - 2013-06-24 ### Fixed - Fixed SAX parser handling of &#nnnn; encoded characters. ## [2.0.3] - 2013-06-12 ### Fixed - Fixed excessive memory allocation issue for very large file parsing (half a gig). ## [2.0.2] - 2013-06-7 ### Fixed - Fixed buffer sliding window off by 1 error in the SAX parser. ## [1] -2-.0 ### Fixed - Added an attrs_done callback to the sax parser that will be called when all attributes for an element have been read. - Fixed bug in SAX parser where raising an exception in the handler routines would not cleanup. The test put together by griffinmyers was a huge help. - Reduced stack use in a several places to improve fiber support. - Changed exception handling to assure proper cleanup with new stack minimizing. ## [2.0.0] - 2013-04-16 ### Fixed - The SAX parser went through a significant re-write. The options have changed. It is now 15% faster on large files and much better at recovering from errors. So much so that the tolerant option was removed and is now the default and only behavior. A smart option was added however. The smart option recognizes a file as an HTML file and will apply a simple set of validation rules that allow the HTML to be parsed more reasonably. Errors will cause callbacks but the parsing continues with the best guess as to how to recover. Rubymaniac has helped with testing and prompted the rewrite to support parsing HTML pages. - HTML is now supported with the SAX parser. The parser knows some tags like \ or \ do not have to be closed. Other hints as to how to parse and when to raise errors are also included. The parser does it's best to continue parsing even after errors. - Added symbolize option to the sax parser. This option, if set to false will use strings instead of symbols for element and attribute names. - A contrib directory was added for people to submit useful bits of code that can be used with Ox. The first contributor is Notezen with a nice way of building XML. ## [1.9.4] - 2013-03-24 ### Fixed - SAX tolerant mode handle multiple elements in a document better. ## [1.9.3] - 2013-03-22 ### Fixed - mcarpenter fixed a compile problem with Cygwin. - Now more tolerant when the :effort is set to :tolerant. Ox will let all sorts of errors typical in HTML documents pass. The result may not be perfect but at least parsed results are returned. - Attribute values need not be quoted or they can be quoted with single quotes or there can be no =value are all. - Elements not terminated will be terminated by the next element termination. This effect goes up until a match is found on the element name. - SAX parser also given a :tolerant option with the same tolerance as the string parser. ## [1.9.2] - 2013-03-9 ### Fixed - Fixed bug in the sax element name check that cause a memory write error. ## [1.9.1] - 2013-02-27 ### Fixed - Fixed the line numbers to be the start of the elements in the sax parser. ## [1.9.0] - 2013-02-25 ### Fixed - Added a new feature to Ox::Element.locate() that allows filtering by node Class. - Added feature to the Sax parser. If @line is defined in the handler it is set to the line number of the xml file before making callbacks. The same goes for @column but it is updated with the column. ## [1.8.9] - 2013-02-21 ### Fixed - Fixed bug in element start and end name checking. ## [1.8.8] - 2013-02-17 ### Fixed - Fixed bug in check for open and close element names matching. ## [7] -1-.8 ### Fixed - Added a correct check for element open and close names. - Changed raised Exceptions to customer classes that inherit from StandardError. - Fixed a few minor bugs. ## [1.8.6] - 2013-02-7 ### Fixed - Removed broken check for matching start and end element names in SAX mode. The names are still included in the handler callbacks so the user can perform the check is desired. ## [1.8.5] - 2013-02-3 ### Fixed - added encoding support for JRuby where possible when in 1.9 mode. ## [1.8.4] - 2013-01-25 ### Fixed - Applied patch by mcarpenter to fix solaris issues with build and remaining undefined @nodes. ## [1.8.3] - 2013-01-24 ### Fixed - Sax parser now honors encoding specification in the xml prolog correctly. ## [1.8.2] - 2013-01-18 ### Fixed - Ox::Element.locate no longer raises and exception if there are no child nodes. - Dumping an XML document no longer puts a carriage return after processing instructions. ## [1.8.1] - 2012-December-17 ### Fixed - Fixed bug that caused a crash when an invalid xml with two elements and no was parsed. (issue #28) - Modified the SAX parser to not strip white space from the start of string content. ## [1.8.0] - 2012-December-11 ### Fixed - Added more complete support for processing instructions in both the generic parser and in the sax parser. This change includes and additional sax handler callback for the end of the instruction processing. ## [1.7.1] - 2012-December-6 ### Fixed - Pulled in sharpyfox's changes to make Ox with with Windows. (issue #24) - Fixed bug that ignored white space only text elements. (issue #26) ## [1.7.0] - 2012-11-27 ### Fixed - Added support for BOM in the SAX parser. ## [1.6.9] - 2012-11-25 ### Fixed - Added support for BOM. They are honored for and handled correctly for UTF-8. Others cause encoding issues with Ruby or raise an error as others are not ASCII compatible.. ## [1.6.8] - 2012-11-18 ### Fixed - Changed extconf.rb to use RUBY_PLATFORM. ## [1.6.7] - 2012-11-15 ### Fixed - Now uses the encoding of the imput XML as the default encoding for the parsed output if the default options encoding is not set and the encoding is not set in the XML file prolog. ## [1.6.5] - 2012-10-25 ### Fixed - Special character handling now supports UCS-2 and UCS-4 Unicode characters as well as UTF-8 characters. ## [1.6.4] - 2012-10-24 ### Fixed - Special character handling has been improved. Both hex and base 10 numeric values are allowed up to a 64 bit number for really long UTF-8 characters. ## [1.6.3] - 2012-10-22 ### Fixed - Fixed compatibility issues with Linux (Ubuntu) mostly related to pointer sizes. ## [1.6.2] - 2012-10-7 ### Fixed - Added check for Solaris and Linux builds to not use the timezone member of time struct (struct tm). ## [1.6.1] - 2012-10-7 ### Fixed - Added check for Solaris builds to not use the timezone member of time struct (struct tm). ox-2.14.17/Gemfile000066400000000000000000000001551445411231300136060ustar00rootroot00000000000000source 'https://rubygems.org' gemspec group :development do gem 'rubocop', '~> 1.47', require: false end ox-2.14.17/LICENSE000066400000000000000000000020651445411231300133220ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2012 Peter Ohler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.ox-2.14.17/README.md000066400000000000000000000254771445411231300136100ustar00rootroot00000000000000# Ox gem A fast XML parser and Object marshaller as a Ruby gem. [![CI](https://github.com/ohler55/ox/actions/workflows/CI.yml/badge.svg)](https://github.com/ohler55/ox/actions/workflows/CI.yml) ## Installation gem install ox ## Documentation *Documentation*: http://www.ohler.com/ox ## Source *GitHub* *repo*: https://github.com/ohler55/ox *RubyGems* *repo*: https://rubygems.org/gems/ox ## Support [Get supported Ox with a Tidelift Subscription.](https://tidelift.com/subscription/pkg/rubygems-ox?utm_source=rubygems-ox&utm_medium=referral&utm_campaign=readme) Security updates are [supported](https://tidelift.com/security). ## Links of Interest [Ruby XML Gem Comparison](http://www.ohler.com/dev/xml_with_ruby/xml_with_ruby.html) for a performance comparison between Ox, Nokogiri, and LibXML. [Fast Ruby XML Serialization](http://www.ohler.com/dev/ruby_object_xml_serialization/ruby_object_xml_serialization.html) to see how Ox can be used as a faster replacement for Marshal. *Fast JSON parser and marshaller on RubyGems*: https://rubygems.org/gems/oj *Fast JSON parser and marshaller on GitHub*: https://github.com/ohler55/oj ## Release Notes See [CHANGELOG.md](CHANGELOG.md) ## Description Optimized XML (Ox), as the name implies was written to provide speed optimized XML and now HTML handling. It was designed to be an alternative to Nokogiri and other Ruby XML parsers in generic XML parsing and as an alternative to Marshal for Object serialization. Unlike some other Ruby XML parsers, Ox is self contained. Ox uses nothing other than standard C libraries so version issues with libXml are not an issue. Marshal uses a binary format for serializing Objects. That binary format changes with releases making Marshal dumped Object incompatible between some versions. The use of a binary format make debugging message streams or file contents next to impossible unless the same version of Ruby and only Ruby is used for inspecting the serialize Object. Ox on the other hand uses human readable XML. Ox also includes options that allow strict, tolerant, or a mode that automatically defines missing classes. It is possible to write an XML serialization gem with Nokogiri or other XML parsers but writing such a package in Ruby results in a module significantly slower than Marshal. This is what triggered the start of Ox development. Ox handles XML documents in three ways. It is a generic XML parser and writer, a fast Object / XML marshaller, and a stream SAX parser. Ox was written for speed as a replacement for Nokogiri, Ruby LibXML, and for Marshal. As an XML parser it is 2 or more times faster than Nokogiri and as a generic XML writer it is as much as 20 times faster than Nokogiri. Of course different files may result in slightly different times. As an Object serializer Ox is up to 6 times faster than the standard Ruby Marshal.dump() and up to 3 times faster than Marshal.load(). The SAX like stream parser is 40 times faster than Nokogiri and more than 13 times faster than LibXML when validating a file with minimal Ruby callbacks. Unlike Nokogiri and LibXML, Ox can be tuned to use only the SAX callbacks that are of interest to the caller. (See the perf_sax.rb file for an example.) Ox is compatible with Ruby 2.3, 2.4, 2.5, 2.6, 2.7, 3.0. ### Object Dump Sample: ```ruby require 'ox' class Sample attr_accessor :a, :b, :c def initialize(a, b, c) @a = a @b = b @c = c end end # Create Object obj = Sample.new(1, "bee", ['x', :y, 7.0]) # Now dump the Object to an XML String. xml = Ox.dump(obj) # Convert the object back into a Sample Object. obj2 = Ox.parse_obj(xml) ``` ### Generic XML Writing and Parsing: ```ruby require 'ox' doc = Ox::Document.new instruct = Ox::Instruct.new(:xml) instruct[:version] = '1.0' instruct[:encoding] = 'UTF-8' instruct[:standalone] = 'yes' doc << instruct top = Ox::Element.new('top') top[:name] = 'sample' doc << top mid = Ox::Element.new('middle') mid[:name] = 'second' top << mid bot = Ox::Element.new('bottom') bot[:name] = 'third' bot << 'text at bottom' mid << bot other_elements = Ox::Element.new('otherElements') other_elements << Ox::CData.new('John Smith') other_elements << Ox::Comment.new('Director\'s commentary') # other_elements << Ox::DocType.new('content') other_elements << Ox::Raw.new('Be carefull with this! Direct inject into XML!') top << other_elements xml = Ox.dump(doc) # xml = # # # # text at bottom # # # John Smith]]> # # Be carefull with this! Direct inject into XML! # # ``` ### HTML Parsing: Ox can be used to parse HTML with a few options changes. HTML is often loose in regard to conformance. For HTML parsing try these options. ```ruby Ox.default_options = { mode: :generic, effort: :tolerant, smart: true } ``` ### SAX XML Parsing: ```ruby require 'stringio' require 'ox' class Sample < ::Ox::Sax def start_element(name); puts "start: #{name}"; end def end_element(name); puts "end: #{name}"; end def attr(name, value); puts " #{name} => #{value}"; end def text(value); puts "text #{value}"; end end io = StringIO.new(%{ }) handler = Sample.new() Ox.sax_parse(handler, io) # outputs # start: top # name => sample # start: middle # name => second # start: bottom # name => third # end: bottom # end: middle # end: top ``` ### Yielding results immediately while SAX XML Parsing: ```ruby require 'stringio' require 'ox' class Yielder < ::Ox::Sax def initialize(block); @yield_to = block; end def start_element(name); @yield_to.call(name); end end io = StringIO.new(%{ }) proc = Proc.new { |name| puts name } handler = Yielder.new(proc) puts "before parse" Ox.sax_parse(handler, io) puts "after parse" # outputs # before parse # top # middle # bottom # after parse ``` ### Parsing XML into a Hash (fast) ```ruby require 'ox' xml = %{ Rock bottom } puts Ox.load(xml, mode: :hash) puts Ox.load(xml, mode: :hash_no_attrs) #{:top=>[{:name=>"sample"}, {:middle=>[{:name=>"second"}, {:bottom=>[{:name=>"third"}, "Rock bottom"]}]}]} #{:top=>{:middle=>{:bottom=>"Rock bottom"}}} ``` ### Object XML format The XML format used for Object encoding follows the structure of the Object. Each XML element is encoded so that the XML element name is a type indicator. Attributes of the element provide additional information such as the Class if relevant, the Object attribute name, and Object ID if necessary. The type indicator map is: - **a** => `Array` - **b** => `Base64` - only for legacy loads - **c** => `Class` - **f** => `Float` - **g** => `Regexp` - **h** => `Hash` - **i** => `Fixnum` - **j** => `Bignum` - **l** => `Rational` - **m** => `Symbol` - **n** => `FalseClass` - **o** => `Object` - **p** => `Ref` - **r** => `Range` - **s** => `String` - **t** => `Time` - **u** => `Struct` - **v** => `Complex` - **x** => `Raw` - **y** => `TrueClass` - **z** => `NilClass` If the type is an Object, type 'o' then an attribute named 'c' should be set with the full Class name including the Module names. If the XML element represents an Object then a sub-elements is included for each attribute of the Object. An XML element attribute 'a' is set with a value that is the name of the Ruby Object attribute. In all cases, except for the Exception attribute hack the attribute names begin with an @ character. (Exception are strange in that the attributes of the Exception Class are not named with a @ suffix. A hack since it has to be done in C and can not be done through the interpreter.) Values are encoded as the text portion of an element or in the sub-elements of the principle. For example, a Fixnum is encoded as: ```xml 123 ``` An Array has sub-elements and is encoded similar to this example. ```xml 1 abc ``` A Hash is encoded with an even number of elements where the first element is the key and the second is the value. This is repeated for each entry in the Hash. An example is of { 1 => 'one', 2 => 'two' } encoding is: ```xml 1 one 2 two ``` Ox supports circular references where attributes of one Object can refer to an Object that refers back to the first Object. When this option is used an Object ID is added to each XML Object element as the value of the 'a' attribute. ## Contributors ### Code Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. ### Financial Contributors Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/ohler/contribute)] #### Individuals #### Organizations Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/ohler/contribute)] ox-2.14.17/Rakefile000066400000000000000000000010111445411231300137500ustar00rootroot00000000000000# frozen_string_literal: true require 'bundler/gem_tasks' require 'rake/extensiontask' require 'rake/testtask' Rake::ExtensionTask.new('ox') do |ext| ext.lib_dir = 'lib/ox' end task test_all: [:clean, :compile] do $stdout.flush exitcode = 0 status = 0 cmds = 'ruby test/tests.rb -v' $stdout.syswrite "\n#{'#' * 90}\n#{cmds}\n" Bundler.with_original_env do status = system(cmds) end exitcode = 1 unless status Rake::Task['test'].invoke exit(1) if exitcode == 1 end task default: :test_all ox-2.14.17/SECURITY.md000066400000000000000000000005241445411231300141040ustar00rootroot00000000000000# Security Policy ## Supported Versions Use this section to tell people about which versions of your project are currently being supported with security updates. | Version | Supported | | ------- | ------------------ | | 2.11.0 | :white_check_mark: | ## Reporting a Vulnerability Report a vulnerability by creating an issue. ox-2.14.17/build_test.sh000077500000000000000000000017201445411231300150070ustar00rootroot00000000000000#!/bin/sh # 1.8.7-p374\ for ruby in \ rbx-2.2.6\ 1.9.3-p547\ 2.1.5\ 2.2.2\ 2.3.3\ 2.4.1 \ do echo "\n********************************************************************************" echo "Building $ruby\n" cd ext/ox rbenv local $ruby ruby extconf.rb make clean find . -name "*.rbc" -exec rm {} \; make echo "\nRunning tests for $ruby" cd ../../test rbenv local $ruby ./tests.rb cd sax rbenv local $ruby ./sax_test.rb cd ../.. echo "\n" done PATH=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin:$PATH echo "\n********************************************************************************" echo "Building OS X Ruby\n" cd ext/ox ruby extconf.rb make clean make echo "\nRunning tests for OS X Ruby" cd ../../test ./tests.rb ./sax/sax_test.rb cd .. echo "resetting to 2.4.1\n" cd ext/ox rbenv local 2.4.1 cd ../../test rbenv local 2.4.1 cd sax rbenv local 2.4.1 cd ../.. echo "\n" ox-2.14.17/contrib/000077500000000000000000000000001445411231300137525ustar00rootroot00000000000000ox-2.14.17/contrib/README.md000066400000000000000000000005421445411231300152320ustar00rootroot00000000000000# Contributions This directory is for people who have found useful functions and routines that makes use of or enhances Ox that they would like to share with others. Fell free to put in a pull request if you would like to contribute. Place the code and the tests in a file with a title that provides some clue as to the contents and I'll pull it in. ox-2.14.17/contrib/sax_benchmark.rb000066400000000000000000000045751445411231300171170ustar00rootroot00000000000000# All credit to https://github.com/hakanensari # Taken from https://gist.github.com/hakanensari/3078932 require 'benchmark' require 'stringio' require 'nokogiri' require 'ox' io = StringIO.new %{ 0816614024 Gilles Deleuze Felix Guattari Thousand Plateaus 0231081596 Gilles Deleuze Difference and Repetition }.strip.gsub(/>\s+<') class OxHandler < Ox::Sax attr :root def initialize super @stack = [@node = @root = {}] end def attr(key, val) @node[key] = val end def end_element(key) child = @stack.pop @node = @stack.last case @node[key] when Array @node[key] << child when Hash @node[key] = [@node[key], child] else if child.keys == [:__content__] @node[key] = child[:__content__] else @node[key] = child end end end def start_element(key) @stack << @node = {} end def text(val) @node[:__content__] = val end end class NokogiriHandler < Nokogiri::XML::SAX::Document attr :root def characters(val) (@node['__content__'] ||= '') << val end def end_element(key) child = @stack.pop @node = @stack.last case @node[key] when Array @node[key] << child when Hash @node[key] = [@node[key], child] else if child.keys == ['__content__'] @node[key] = child['__content__'] else @node[key] = child end end end def start_element(key, attrs = []) @stack << @node = {} attrs.each do |attr| key, val = *attr @node[key] = val end end def start_document @stack = [@root = {}] end end n = 10_000 Benchmark.bmbm do |b| b.report('ox') do n.times do io.rewind handler = OxHandler.new Ox.sax_parse handler, io end end b.report('nokogiri') do n.times do io.rewind handler = NokogiriHandler.new parser = Nokogiri::XML::SAX::Parser.new handler parser.parse io end end end ox-2.14.17/contrib/xbuilder.rb000066400000000000000000000013411445411231300161140ustar00rootroot00000000000000# Contributed by Notezen require 'ox' module Ox module XBuilder # args = attributes and/or children in any order, multiple appearance is possible # @overload build(name,attributes,children) # @param [String] name name of the Element # @param [Hash] attributes # @param [String|Element|Array] children text, child element or array of elements def x(name, *args) n = Element.new(name) for arg in args case arg when Hash arg.each { |k, v| n[k.to_s] = v } when Array arg.each { |c| n << c if c} else n << arg if arg end end n end def x_if(condition, *args) x(*args) if condition end end end ox-2.14.17/contrib/xbuilder_test.rb000077500000000000000000000021131445411231300171540ustar00rootroot00000000000000#!/usr/bin/env ruby # Contributed by Notezen $: << File.join(File.dirname(__FILE__), '../lib') $: << File.join(File.dirname(__FILE__), '../ext') $: << File.join(File.dirname(__FILE__), '.') require 'test/unit' require 'ox' require 'xbuilder' class XBuilderTest < Test::Unit::TestCase include Ox::XBuilder def test_build xml = ' some text another text ' children = [ x_if(true, 'child3'), x('child4', 'another text', 'atr4' => 'atr4_value'), x_if(false, 'child5') ] n=x('parent', x('child1', { 'atr1'=>'atr1_value', :atr2 => 'atr2_value' }, x('subchild1', 'some text'), x('subchild2', { 'atr3' => 'default_value' }, { 'atr3' => 'atr3_value' }, x('sometag'), x_if(false, 'never'))), children) assert_equal(Ox.dump(n), Ox.dump(Ox.parse(xml))) end end ox-2.14.17/examples/000077500000000000000000000000001445411231300141305ustar00rootroot00000000000000ox-2.14.17/examples/gen.rb000077500000000000000000000026741445411231300152420ustar00rootroot00000000000000#!/usr/bin/env ruby # This example demonstrates loading an XML modifying it and then dumping it. # Use the current repo if run from the examples directory. ox_dir = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH << File.join(ox_dir, 'ext') $LOAD_PATH << File.join(ox_dir, 'lib') require 'ox' xml = %{ mutant 5 dog } # Load the XML into a set of Ox::Nodes. doc = Ox.load(xml, mode: :generic) # Once an Ox::Document is loaded it can be inspected and modified. A Doc has a # root. Calling doc.root will give a node that is the root of the XML which is # the Park.Animal element. root = doc.root puts "root element name: #{root.name}" # The Ox::Element.locate method can be used similar to XPath. It does not have # all the features of XPath but it does help dig into an XML. Look for any # descendent of the root that has a type attribute and return those attribute # values. puts "descendent type attribute value: #{root.locate('*/@type')}" # Delete 'i' element by iterating over the root's nodes and look for one named # friends. The locate method could also be used. root.nodes.each do |n| n.nodes.delete_if { |child| child.name == 'i' } if n.name == 'friends' end # Lets take a look at the changes by dumping the doc. xml2 = Ox.dump(doc) puts "modified XML: #{xml2}" ox-2.14.17/examples/hashi.rb000077500000000000000000000020531445411231300155540ustar00rootroot00000000000000#!/usr/bin/env ruby # This example demonstrates the use of Ox.load using the :hash and # :hash_no_attrs modes. # Use the current repo if run from the examples directory. ox_dir = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH << File.join(ox_dir, 'ext') $LOAD_PATH << File.join(ox_dir, 'lib') require 'ox' # load or use this sample string. xml = %{ mutant 5 dog } doc = Ox.load(xml, mode: :hash) puts "as hash with Symbol element names: #{doc}" # Load the XML and convert to a Hash. By default element names are # symbolized. By using the :symbolize_keys option and setting it to false the # element names will be strings. doc = Ox.load(xml, mode: :hash, symbolize_keys: false) puts "as hash with String element names: #{doc}" # The :hash_no_attrs mode leaves attributes out of the resulting Hash. doc = Ox.load(xml, mode: :hash_no_attrs) puts "as hash_no_attrs: #{doc}" ox-2.14.17/examples/obj.rb000077500000000000000000000015571445411231300152420ustar00rootroot00000000000000#!/usr/bin/env ruby # This example demonstrates encoding and decoding a Ruby object. # Use the current repo if run from the examples directory. ox_dir = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH << File.join(ox_dir, 'ext') $LOAD_PATH << File.join(ox_dir, 'lib') require 'ox' # Define a class that will be used for instances that are encoded and decoded. class Classy def initialize(a, b) @a = a @b = b end def to_s "Classy a: #{@a}, b: #{@b}" end end obj = Classy.new(23, ['abc', { x: true }]) doc = Ox.dump(obj, mode: :object) # The encoded format is not important other and should ot be generated by # hand. It is of interest only for the curious. puts "encoded object:\n#{doc}" # Now convert back to a Ruby object. obj2 = Ox.load(doc, mode: :object) # Looks the same, print it out to check. puts "decoded object: #{obj2}" ox-2.14.17/examples/sax_ractor.rb000077500000000000000000000156751445411231300166430ustar00rootroot00000000000000#!/usr/bin/env ruby require 'ox' require 'pathname' # Silence Ractor warning in Ruby 3.0.x Warning[:experimental] = false abort('This Ractor example requires at least Ruby 3.0') if RUBY_VERSION.start_with?('2') # Example/test script for `Ractor`-based `Ox::Sax` parsing. # In the Real World™ we probably wouldn't create a single-use `Ractor` for # every argument, but this is primarily a test of `rb_ext_ractor_safe` for Ox. # Miniature example Ractor-based `shared-mime-info` Ox handler à la `CHECKING::YOU::OUT`: # https://github.com/okeeblow/DistorteD/tree/NEW-SENSATION/CHECKING-YOU-OUT class Saxtor < Ox::Sax # We will fill this `Struct` as we parse, # yield it if its `ietf` matches our `needle`, # and throw it away otherwise. CYO = Struct.new(:ietf, :globs, :description) do def initialize(ietf = nil, globs = [], description = nil) super(ietf, globs, description) end def to_s # Pretty print "#{self[:description]} (#{self[:ietf]}) [#{ self[:globs]&.map(&File.method(:extname))&.join(',') }]" end def inspect "#" end end # Set up our parsing environment and open a file handle for our XML. def initialize(parent, haystack) super @parse_stack = [] # Track our current Element as we parse. @parent = parent # `Ractor` that instantiated us. @haystack = File.open(haystack, File::Constants::RDONLY) @haystack.advise(:sequential) end # Stratch `Struct`. def cyo @cyo ||= CYO.new end # Wax on… def start_element(name) @parse_stack.push(name) case @parse_stack.last when :"mime-type" then @cyo = nil # Clear out leftovers between types. end end # …wax off. def end_element(name) case @parse_stack.last when :"mime-type" # Save the scratch `Struct` if we matched our needle while building it. @out = cyo.dup if @i_can_haz @i_can_haz = false end @parse_stack.pop end # Element attribute callback — Ox::Sax::Value version def attr_value(name, value) case [@parse_stack.last, name] in :"mime-type", :type cyo[:ietf] = value.as_s # If we found our needle then we will yield the scratch `CYO` instead of `nil`. @i_can_haz = true if value.as_s == @needle in :glob, :pattern cyo[:globs].append(value.as_s) else nil end end # Element text content callback, e.g. for TEXT # This part. --------^ def text(element_text) case @parse_stack.last when :comment # This will end up being the `last` locale (probably `zh_TW`) # because I don't want to implement locale checking for a test script lol cyo[:description] = element_text end end # Start our search for a given `needle` in our open `haystack`. def awen(needle, **kwargs) @needle = needle # What IETF Media-Type should we find? (e.g. `'image/jpeg'`) @i_can_haz = false # Did we find our `needle`? (obviously not yet) @haystack.rewind # Pon de Replay # Do the thing. Ox.sax_parse( self, # Instance of a class that responds to `Ox::Sax`'s callback messages. @haystack, # IO stream or String of XML to parse. Won't close File handles automatically. **{ convert_special: true, # [boolean] Convert encoded entities back to their unencoded form, e.g. `"<"` to `"<"`. skip: :skip_off, # [:skip_none|:skip_return|:skip_white|:skip_off] (from Element text/value) Strip CRs, whitespace, or nothing. smart: false, # [boolean] Toggle Ox's built-in hints for HTML parsing: https://github.com/ohler55/ox/blob/master/ext/ox/sax_hint.c strip_namespace: true, # [nil|String|true|false] (from Element names) Strip no namespaces, all namespaces, or a specific namespace. symbolize: true, # [boolean] Fill callback method `name` arguments with Symbols instead of with Strings. intern_string_values: true # [boolean] Intern (freeze and deduplicate) String return values. }.update(kwargs), ) # Let our parent `#take` our needle-equivalent `CYO`, or `nil`. Ractor.yield(@out) end # def awen end # class Saxtor # Fancy "usage" help `String` fragment to concat with specific error messages. usage = <<~PLZ Usage: `sax_ractor.rb [SHARED-MIME-INFO_XML_PATH] [IETF_MEDIA_TYPES]…` Common file paths: - FreeBSD: `${LOCALBASE}/share/mime/packages/freedesktop.org.xml` (probably `/usr/local`) https://www.freshports.org/misc/shared-mime-info/ - Linux: `/usr/share/mime/packages/freedesktop.org.xml` - macOS: `/opt/homebrew/share/mime/packages/freedesktop.org.xml` (Homebrew) `/opt/local/share/mime/packages/freedesktop.org.xml` (MacPorts) https://formulae.brew.sh/formula/shared-mime-info PLZ # Bail out if we were given a nonexistant file. unless ARGV.size > 0 abort("Please provide the path to a `shared-mime-info` XML package \ and some media-type query arguments (e.g. 'image/jpeg')".concat(usage)) end haystack = Pathname.new(ARGV.first) abort("#{haystack} does not exist") unless haystack.exist? and haystack.file? # *Judicator Aldaris voice* "YOU HAVE NOT ENOUGH ARGUMENTS." abort("Please provide some media-type query arguments (e.g. 'image/jpeg')".concat(usage)) unless ARGV.size > 1 # We can use `Ractor::make_shareable()` for larger traversable data structures, # but freezing should be enough to share a `Pathname`. # Resolve symlinks etc with `#realpath` before we freeze. haystack = haystack.realpath.freeze needles = ARGV[1...] # Hamburger Style. puts 'Parallel Ractors' # Create one `Ractor` for every given media-type argument moo = ['Heifer', 'Cow', 'Bull', 'Steer'].tally head_count = needles.size - 1 herd = (0..head_count).map do # Give our worker `Ractor` a name, otherwise its `#name` will return `nil`. individual = moo.keys.sample moo[individual] += 1 Ractor.new(haystack, name: "#{individual} #{moo[individual] - 1}") do |haystack| # Initialize an `Ox::Sax` handler for our given source file. handler = Saxtor.new(Ractor.current, haystack) # Now we can `#send` a needle to this `Ractor` and make it search the haystack! while ietf_string = Ractor.receive Ractor.yield(handler.awen(ietf_string)) end end end # Send our arguments to our herd in a 1:1 mapping (0..head_count).each { herd[_1].send(needles[_1]) } # Wait for every `Ractor` to have a result, and then pretty print all of them :) pp (0..head_count).map do [herd[_1], herd[_1].take] end.map do "#{_1.name} gave us #{_2 || 'nothing'}" end # Hotdog Style. puts puts 'Serial Ractor' # Create a single `Ractor` and send every media-type to it in series. only_one_ox = Ractor.new(haystack, name: 'ONLY ONE OX') do |haystack| handler = Saxtor.new(Ractor.current, haystack) while ietf_string = Ractor.receive handler.awen(ietf_string) end end (0..head_count).each { only_one_ox.send(needles[_1]) } pp "#{only_one_ox.name} gave us #{(0..head_count).map { only_one_ox.take }}" ox-2.14.17/examples/saxy.html000066400000000000000000000010321445411231300157760ustar00rootroot00000000000000 Saxy

First Line

One Level Deep


Deeper

ox-2.14.17/examples/saxy.rb000077500000000000000000000023611445411231300154460ustar00rootroot00000000000000#!/usr/bin/env ruby # This example demonstrates the use of the Ox.sax_parse method. An XML string # is parsed and a list of element names if built. # Use the current repo if run from the examples directory. ox_dir = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH << File.join(ox_dir, 'ext') $LOAD_PATH << File.join(ox_dir, 'lib') require 'ox' # First create a handler for the SAX callbacks. A Hash is used to collect the # element names. This is a quick way to make sure the collected names are # unique. Only the start_element is implemented as that is all that is needed # to collect names. There is no need to inherit from Ox::Sax but tht class # includes the private version of all the methods that can be made publis. class Saxy def initialize # super @names = {} end def names @names.keys end def start_element(name) @names[name] = nil end end # The XML can be a string or a IO instance. xml = %{ mutant 5 dog } # Create an instance of the handler. handler = Saxy.new Ox.sax_html(handler, xml) puts "element names: #{handler.names}" ox-2.14.17/examples/saxy_html.rb000077500000000000000000000064411445411231300164750ustar00rootroot00000000000000#!/usr/bin/env ruby # This example demonstrates the use of the Ox.sax_html parser and the # Ox.Builder. The parser is used to parse and HTML file and add a # `class="ppp"` to each '

' element start. # # The approach taken is to build while parsing. An HTML parse is started and a # builder call is made on each parser callback. If the element is a 'p' then # the class attribute is added. All others remain the same. # Use the current repo if run from the examples directory. ox_dir = File.dirname(File.dirname(File.expand_path(__FILE__))) $LOAD_PATH << File.join(ox_dir, 'ext') $LOAD_PATH << File.join(ox_dir, 'lib') require 'ox' # First create a handler for the SAX callbacks. The class instances include a # builder that builds as parsing takes place. class Saxy < Ox::Sax VOID_ELEMENTS = [:area, :base, :br, :col, :embed, :hr, :img, :input, :link, :meta, :param, :source, :track, :wbr] def initialize super # The build is created with an indentation of 2 but that can be changed to # the desired indentation. @builder = Ox::Builder.new(indent: 2) # element_name and attributes are used for deferred writing of the element # start. @element_name = nil @attrs = {} end def to_s @builder.to_s end # The builder creates element starts with attributes but the parser uses a # seprate call for attributes and element starts. To deal with the # difference keep track of the start name and attributes as they are # added. When another callback other than attributes is called write any # pending element start. def push_element return if @element_name.nil? # Add the class attribute if the element is a

element. @attrs[:class] = 'ppp' if :p == @element_name # Check @void_elements to determine how the element start would be # written. HTML includes void elements that are self closing so those # should be handled correctly. if VOID_ELEMENTS.include?(@element_name) @builder.void_element(@element_name, @attrs) else @builder.element(@element_name, @attrs) end # Reset the element name. @element_name = nil @attrs = {} end def start_element(name) push_element @element_name = name end def attr(name, value) @attrs[name] = value end def doctype(value) push_element @builder.doctype(value) end def comment(value) push_element @builder.comment(value) end def text(value) push_element @builder.text(value) end def end_element(name) push_element @builder.pop unless VOID_ELEMENTS.include?(name) end # Just in case there is a parse error this will display the error along with # where the error occurred in the XML file. def error(message, line, column) puts "*-*-* error at #{line}:#{column}: #{message}" end end # Load the XML file. The Ox.sax_html also handles IO objects. xml = File.read('saxy.html') # Create an instance of the handler. handler = Saxy.new Ox.sax_html(handler, xml) # For debugging uncomment these lines. # puts "******************** original *************************\n#{xml}" # puts "******************** modifified ***********************\n#{handler.to_s}" # For benchmarks these lines should be repeated to parse and to generate a # modified XML string. # handler = Saxy.new() # Ox.sax_html(handler, xml) # handler.to_s ox-2.14.17/ext/000077500000000000000000000000001445411231300131125ustar00rootroot00000000000000ox-2.14.17/ext/ox/000077500000000000000000000000001445411231300135405ustar00rootroot00000000000000ox-2.14.17/ext/ox/attr.h000066400000000000000000000040141445411231300146620ustar00rootroot00000000000000/* attr.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_ATTR_H #define OX_ATTR_H #include #define ATTR_STACK_INC 8 typedef struct _attr { const char *name; const char *value; } *Attr; typedef struct _attrStack { struct _attr base[ATTR_STACK_INC]; Attr head; /* current stack */ Attr end; /* stack end */ Attr tail; /* pointer to one past last element name on stack */ } *AttrStack; inline static void attr_stack_init(AttrStack stack) { stack->head = stack->base; stack->end = stack->base + sizeof(stack->base) / sizeof(struct _attr); stack->tail = stack->head; stack->head->name = 0; } inline static int attr_stack_empty(AttrStack stack) { return (stack->head == stack->tail); } inline static void attr_stack_cleanup(AttrStack stack) { if (stack->base != stack->head) { xfree(stack->head); stack->head = stack->base; } } inline static void attr_stack_push(AttrStack stack, const char *name, const char *value) { if (stack->end <= stack->tail + 1) { size_t len = stack->end - stack->head; size_t toff = stack->tail - stack->head; if (stack->base == stack->head) { stack->head = ALLOC_N(struct _attr, len + ATTR_STACK_INC); memcpy(stack->head, stack->base, sizeof(struct _attr) * len); } else { REALLOC_N(stack->head, struct _attr, len + ATTR_STACK_INC); } stack->tail = stack->head + toff; stack->end = stack->head + len + ATTR_STACK_INC; } stack->tail->name = name; stack->tail->value = value; stack->tail++; stack->tail->name = 0; // terminate } inline static Attr attr_stack_peek(AttrStack stack) { if (stack->head < stack->tail) { return stack->tail - 1; } return 0; } inline static Attr attr_stack_pop(AttrStack stack) { if (stack->head < stack->tail) { stack->tail--; return stack->tail; } return 0; } #endif /* OX_ATTR_H */ ox-2.14.17/ext/ox/base64.c000066400000000000000000000063351445411231300147770ustar00rootroot00000000000000/* base64.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "base64.h" #include #include static char digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* invalid or terminating characters are set to 'X' or \x58 */ static uchar s_digits[256] = "\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x3E\x58\x58\x58\x3F\ \x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x58\x58\x58\x58\x58\x58\ \x58\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\ \x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x58\x58\x58\x58\x58\ \x58\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\ \x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\ \x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58\x58"; void to_base64(const uchar *src, int len, char *b64) { const uchar *end3; int len3 = len % 3; uchar b1, b2, b3; end3 = src + (len - len3); while (src < end3) { b1 = *src++; b2 = *src++; b3 = *src++; *b64++ = digits[(uchar)(b1 >> 2)]; *b64++ = digits[(uchar)(((b1 & 0x03) << 4) | (b2 >> 4))]; *b64++ = digits[(uchar)(((b2 & 0x0F) << 2) | (b3 >> 6))]; *b64++ = digits[(uchar)(b3 & 0x3F)]; } if (1 == len3) { b1 = *src++; *b64++ = digits[b1 >> 2]; *b64++ = digits[(b1 & 0x03) << 4]; *b64++ = '='; *b64++ = '='; } else if (2 == len3) { b1 = *src++; b2 = *src++; *b64++ = digits[b1 >> 2]; *b64++ = digits[((b1 & 0x03) << 4) | (b2 >> 4)]; *b64++ = digits[(b2 & 0x0F) << 2]; *b64++ = '='; } *b64 = '\0'; } unsigned long b64_orig_size(const char *text) { const char *start = text; unsigned long size = 0; if ('\0' != *text) { for (; 0 != *text; text++) { } size = (text - start) * 3 / 4; text--; if ('=' == *text) { size--; text--; if ('=' == *text) { size--; } } } return size; } void from_base64(const char *b64, uchar *str) { uchar b0, b1, b2, b3; while (1) { if ('X' == (b0 = s_digits[(uchar)*b64++])) { break; } if ('X' == (b1 = s_digits[(uchar)*b64++])) { break; } *str++ = (b0 << 2) | ((b1 >> 4) & 0x03); if ('X' == (b2 = s_digits[(uchar)*b64++])) { break; } *str++ = (b1 << 4) | ((b2 >> 2) & 0x0F); if ('X' == (b3 = s_digits[(uchar)*b64++])) { break; } *str++ = (b2 << 6) | b3; } *str = '\0'; } ox-2.14.17/ext/ox/base64.h000066400000000000000000000005711445411231300150000ustar00rootroot00000000000000/* base64.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef BASE64_H #define BASE64_H typedef unsigned char uchar; #define b64_size(len) ((len + 2) / 3 * 4) extern unsigned long b64_orig_size(const char *text); extern void to_base64(const uchar *src, int len, char *b64); extern void from_base64(const char *b64, uchar *str); #endif /* BASE64_H */ ox-2.14.17/ext/ox/buf.h000066400000000000000000000115721445411231300144730ustar00rootroot00000000000000/* buf.h * Copyright (c) 2014, Peter Ohler * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * - Neither the name of Peter Ohler nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef OX_BUF_H #define OX_BUF_H #include #include #include typedef struct _buf { char *head; char *end; char *tail; int fd; bool err; char base[16384]; } *Buf; inline static void buf_init(Buf buf, int fd, long initial_size) { if (sizeof(buf->base) < (size_t)initial_size) { buf->head = ALLOC_N(char, initial_size); buf->end = buf->head + initial_size - 1; } else { buf->head = buf->base; buf->end = buf->base + sizeof(buf->base) - 1; } buf->tail = buf->head; buf->fd = fd; buf->err = false; } inline static void buf_reset(Buf buf) { buf->head = buf->base; buf->tail = buf->head; } inline static void buf_cleanup(Buf buf) { if (buf->base != buf->head) { free(buf->head); } } inline static size_t buf_len(Buf buf) { return buf->tail - buf->head; } inline static void buf_append_string(Buf buf, const char *s, size_t slen) { if (buf->err) { return; } if (buf->end <= buf->tail + slen) { if (0 != buf->fd) { size_t len = buf->tail - buf->head; if (len != (size_t)write(buf->fd, buf->head, len)) { buf->err = true; return; } buf->tail = buf->head; if (sizeof(buf->base) <= slen) { if (slen != (size_t)write(buf->fd, s, slen)) { buf->err = true; return; } return; } } else { size_t len = buf->end - buf->head; size_t toff = buf->tail - buf->head; size_t new_len = len + slen + len / 2; if (buf->base == buf->head) { buf->head = ALLOC_N(char, new_len); memcpy(buf->head, buf->base, len); } else { REALLOC_N(buf->head, char, new_len); } buf->tail = buf->head + toff; buf->end = buf->head + new_len - 2; } } if (0 < slen) { memcpy(buf->tail, s, slen); } buf->tail += slen; } inline static void buf_append(Buf buf, char c) { if (buf->err) { return; } if (buf->end <= buf->tail) { if (0 != buf->fd) { size_t len = buf->tail - buf->head; if (len != (size_t)write(buf->fd, buf->head, len)) { buf->err = true; } buf->tail = buf->head; } else { size_t len = buf->end - buf->head; size_t toff = buf->tail - buf->head; size_t new_len = len + len / 2; if (buf->base == buf->head) { buf->head = ALLOC_N(char, new_len); memcpy(buf->head, buf->base, len); } else { REALLOC_N(buf->head, char, new_len); } buf->tail = buf->head + toff; buf->end = buf->head + new_len - 2; } } *buf->tail++ = c; //*buf->tail = '\0'; // for debugging } inline static void buf_finish(Buf buf) { if (buf->err) { return; } if (0 != buf->fd) { size_t len = buf->tail - buf->head; if (0 < len && len != (size_t)write(buf->fd, buf->head, len)) { buf->err = true; } fsync(buf->fd); buf->tail = buf->head; } } #endif /* OX_BUF_H */ ox-2.14.17/ext/ox/builder.c000066400000000000000000000630711445411231300153410ustar00rootroot00000000000000/* builder.c * Copyright (c) 2011, 2016 Peter Ohler * All rights reserved. */ #include #include #include #include #include "buf.h" #include "err.h" #include "ox.h" #include "ruby.h" #include "ruby/encoding.h" #include "ruby/version.h" #define MAX_DEPTH 128 typedef struct _element { char *name; char buf[64]; long len; bool has_child; bool non_text_child; } *Element; typedef struct _builder { struct _buf buf; int indent; char encoding[64]; int depth; FILE *file; struct _element stack[MAX_DEPTH]; long line; long col; long pos; } *Builder; static VALUE builder_class = Qundef; static const char indent_spaces[] = "\n " " "; // 128 spaces // The : character is equivalent to 10. Used for replacement characters up to // 10 characters long such as '􏿿'. From // https://www.w3.org/TR/2006/REC-xml11-20060816 #if 0 static const char xml_friendly_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11611156111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; #endif // From 2.3 of the XML 1.1 spec. All over 0x20 except <&", > also. Builder // uses double quotes for attributes. static const char xml_attr_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11611151111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; // From 3.1 of the XML 1.1 spec. All over 0x20 except <&, > also. static const char xml_element_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11111151111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; inline static size_t xml_str_len(const unsigned char *str, size_t len, const char *table) { size_t size = 0; for (; 0 < len; str++, len--) { size += table[*str]; } return size - len * (size_t)'0'; } static void append_indent(Builder b) { if (0 >= b->indent) { return; } if (b->buf.head < b->buf.tail) { int cnt = (b->indent * (b->depth + 1)) + 1; if (sizeof(indent_spaces) <= (size_t)cnt) { cnt = sizeof(indent_spaces) - 1; } buf_append_string(&b->buf, indent_spaces, cnt); b->line++; b->col = cnt - 1; b->pos += cnt; } } static void append_string(Builder b, const char *str, size_t size, const char *table, bool strip_invalid_chars) { size_t xsize = xml_str_len((const unsigned char *)str, size, table); if (size == xsize) { const char *s = str; const char *end = str + size; buf_append_string(&b->buf, str, size); b->col += size; s = strchr(s, '\n'); while (NULL != s) { b->line++; b->col = end - s; s = strchr(s + 1, '\n'); } b->pos += size; } else { char buf[256]; char *end = buf + sizeof(buf) - 1; char *bp = buf; size_t i = size; int fcnt; for (; '\0' != *str && 0 < i; i--, str++) { if ('1' == (fcnt = table[(unsigned char)*str])) { if (end <= bp) { buf_append_string(&b->buf, buf, bp - buf); bp = buf; } if ('\n' == *str) { b->line++; b->col = 1; } else { b->col++; } b->pos++; *bp++ = *str; } else { b->pos += fcnt - '0'; b->col += fcnt - '0'; if (buf < bp) { buf_append_string(&b->buf, buf, bp - buf); bp = buf; } switch (*str) { case '"': buf_append_string(&b->buf, """, 6); break; case '&': buf_append_string(&b->buf, "&", 5); break; case '\'': buf_append_string(&b->buf, "'", 6); break; case '<': buf_append_string(&b->buf, "<", 4); break; case '>': buf_append_string(&b->buf, ">", 4); break; default: // Must be one of the invalid characters. if (!strip_invalid_chars) { rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *str); } break; } } } if (buf < bp) { buf_append_string(&b->buf, buf, bp - buf); bp = buf; } } } static void append_sym_str(Builder b, VALUE v) { const char *s; long len; switch (rb_type(v)) { case T_STRING: s = StringValuePtr(v); len = RSTRING_LEN(v); break; case T_SYMBOL: s = rb_id2name(SYM2ID(v)); len = strlen(s); break; default: rb_raise(ox_arg_error_class, "expected a Symbol or String"); break; } append_string(b, s, len, xml_element_chars, false); } static void i_am_a_child(Builder b, bool is_text) { if (0 <= b->depth) { Element e = &b->stack[b->depth]; if (!e->has_child) { e->has_child = true; buf_append(&b->buf, '>'); b->col++; b->pos++; } if (!is_text) { e->non_text_child = true; } } } static int append_attr(VALUE key, VALUE value, VALUE bv) { Builder b = (Builder)bv; buf_append(&b->buf, ' '); b->col++; b->pos++; append_sym_str(b, key); buf_append_string(&b->buf, "=\"", 2); b->col += 2; b->pos += 2; Check_Type(value, T_STRING); append_string(b, StringValuePtr(value), (int)RSTRING_LEN(value), xml_attr_chars, false); buf_append(&b->buf, '"'); b->col++; b->pos++; return ST_CONTINUE; } static void init(Builder b, int fd, int indent, long initial_size) { buf_init(&b->buf, fd, initial_size); b->indent = indent; *b->encoding = '\0'; b->depth = -1; b->line = 1; b->col = 1; b->pos = 0; } static void builder_free(void *ptr) { Builder b; Element e; int d; if (0 == ptr) { return; } b = (Builder)ptr; buf_cleanup(&b->buf); for (e = b->stack, d = b->depth; 0 < d; d--, e++) { if (e->name != e->buf) { free(e->name); } } xfree(ptr); } static void pop(Builder b) { Element e; if (0 > b->depth) { rb_raise(ox_arg_error_class, "closed too many elements"); } e = &b->stack[b->depth]; b->depth--; if (e->has_child) { if (e->non_text_child) { append_indent(b); } buf_append_string(&b->buf, "name, e->len, xml_element_chars, false); buf_append(&b->buf, '>'); b->col += e->len + 3; b->pos += e->len + 3; if (e->buf != e->name) { free(e->name); e->name = 0; } } else { buf_append_string(&b->buf, "/>", 2); b->col += 2; b->pos += 2; } } static void bclose(Builder b) { while (0 <= b->depth) { pop(b); } if (0 <= b->indent) { buf_append(&b->buf, '\n'); } b->line++; b->col = 1; b->pos++; buf_finish(&b->buf); if (NULL != b->file) { fclose(b->file); } } static VALUE to_s(Builder b) { volatile VALUE rstr; if (0 != b->buf.fd) { rb_raise(ox_arg_error_class, "can not create a String with a stream or file builder."); } if (0 <= b->indent && '\n' != *(b->buf.tail - 1)) { buf_append(&b->buf, '\n'); b->line++; b->col = 1; b->pos++; } *b->buf.tail = '\0'; // for debugging rstr = rb_str_new(b->buf.head, buf_len(&b->buf)); if ('\0' != *b->encoding) { rb_enc_associate(rstr, rb_enc_find(b->encoding)); } return rstr; } /* call-seq: new(options) * * Creates a new Builder that will write to a string that can be retrieved with * the to_s() method. If a block is given it is executed with a single parameter * which is the builder instance. The return value is then the generated string. * * - +options+ - (Hash) formating options * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline * - +:size+ (Fixnum) the initial size of the string buffer */ static VALUE builder_new(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _builder); int indent = ox_default_options.indent; long buf_size = 0; if (1 == argc) { volatile VALUE v; rb_check_type(*argv, T_HASH); if (Qnil != (v = rb_hash_lookup(*argv, ox_indent_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(*argv, ox_size_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = NULL; init(b, 0, indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return to_s(b); } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } } /* call-seq: file(filename, options) * * Creates a new Builder that will write to a file. * * - +filename+ (String) filename to write to * - +options+ - (Hash) formating options * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline * - +:size+ (Fixnum) the initial size of the string buffer */ static VALUE builder_file(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _builder); int indent = ox_default_options.indent; long buf_size = 0; FILE *f; if (1 > argc) { rb_raise(ox_arg_error_class, "missing filename"); } Check_Type(*argv, T_STRING); if (NULL == (f = fopen(StringValuePtr(*argv), "w"))) { xfree(b); rb_raise(rb_eIOError, "%s\n", strerror(errno)); } if (2 == argc) { volatile VALUE v; rb_check_type(argv[1], T_HASH); if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = f; init(b, fileno(f), indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return Qnil; } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } } /* call-seq: io(io, options) * * Creates a new Builder that will write to an IO instance. * * - +io+ (String) IO to write to * - +options+ - (Hash) formating options * - +:indent+ (Fixnum) indentaion level, negative values excludes terminating newline * - +:size+ (Fixnum) the initial size of the string buffer */ static VALUE builder_io(int argc, VALUE *argv, VALUE self) { Builder b = ALLOC(struct _builder); int indent = ox_default_options.indent; long buf_size = 0; int fd; volatile VALUE v; if (1 > argc) { rb_raise(ox_arg_error_class, "missing IO object"); } if (!rb_respond_to(*argv, ox_fileno_id) || Qnil == (v = rb_funcall(*argv, ox_fileno_id, 0)) || 0 == (fd = FIX2INT(v))) { rb_raise(rb_eIOError, "expected an IO that has a fileno."); } if (2 == argc) { volatile VALUE v; rb_check_type(argv[1], T_HASH); if (Qnil != (v = rb_hash_lookup(argv[1], ox_indent_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":indent must be a fixnum.\n"); } indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(argv[1], ox_size_sym))) { if (rb_cInteger != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":size must be a fixnum.\n"); } buf_size = NUM2LONG(v); } } b->file = NULL; init(b, fd, indent, buf_size); if (rb_block_given_p()) { volatile VALUE rb = Data_Wrap_Struct(builder_class, NULL, builder_free, b); rb_yield(rb); bclose(b); return Qnil; } else { return Data_Wrap_Struct(builder_class, NULL, builder_free, b); } } /* call-seq: instruct(decl,options) * * Adds the top level element. * * - +decl+ - (String) 'xml' expected * - +options+ - (Hash) version or encoding */ static VALUE builder_instruct(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); i_am_a_child(b, false); append_indent(b); if (0 == argc) { buf_append_string(&b->buf, "", 7); b->col += 7; b->pos += 7; } else { volatile VALUE v; buf_append_string(&b->buf, "col += 2; b->pos += 2; append_sym_str(b, *argv); if (1 < argc && rb_cHash == rb_obj_class(argv[1])) { int len; if (Qnil != (v = rb_hash_lookup(argv[1], ox_version_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":version must be a Symbol.\n"); } len = (int)RSTRING_LEN(v); buf_append_string(&b->buf, " version=\"", 10); buf_append_string(&b->buf, StringValuePtr(v), len); buf_append(&b->buf, '"'); b->col += len + 11; b->pos += len + 11; } if (Qnil != (v = rb_hash_lookup(argv[1], ox_encoding_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":encoding must be a Symbol.\n"); } len = (int)RSTRING_LEN(v); buf_append_string(&b->buf, " encoding=\"", 11); buf_append_string(&b->buf, StringValuePtr(v), len); buf_append(&b->buf, '"'); b->col += len + 12; b->pos += len + 12; strncpy(b->encoding, StringValuePtr(v), sizeof(b->encoding)); b->encoding[sizeof(b->encoding) - 1] = '\0'; } if (Qnil != (v = rb_hash_lookup(argv[1], ox_standalone_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":standalone must be a Symbol.\n"); } len = (int)RSTRING_LEN(v); buf_append_string(&b->buf, " standalone=\"", 13); buf_append_string(&b->buf, StringValuePtr(v), len); buf_append(&b->buf, '"'); b->col += len + 14; b->pos += len + 14; } } buf_append_string(&b->buf, "?>", 2); b->col += 2; b->pos += 2; } return Qnil; } /* call-seq: element(name,attributes) * * Adds an element with the name and attributes provided. If a block is given * then on closing of the block a pop() is called. * * - +name+ - (String) name of the element * - +attributes+ - (Hash) of the element */ static VALUE builder_element(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); Element e; const char *name; long len; if (1 > argc) { rb_raise(ox_arg_error_class, "missing element name"); } i_am_a_child(b, false); append_indent(b); b->depth++; if (MAX_DEPTH <= b->depth) { rb_raise(ox_arg_error_class, "XML too deeply nested"); } switch (rb_type(*argv)) { case T_STRING: name = StringValuePtr(*argv); len = RSTRING_LEN(*argv); break; case T_SYMBOL: name = rb_id2name(SYM2ID(*argv)); len = strlen(name); break; default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break; } e = &b->stack[b->depth]; if (sizeof(e->buf) <= (size_t)len) { e->name = strdup(name); *e->buf = '\0'; } else { strcpy(e->buf, name); e->name = e->buf; } e->len = len; e->has_child = false; e->non_text_child = false; buf_append(&b->buf, '<'); b->col++; b->pos++; append_string(b, e->name, len, xml_element_chars, false); if (1 < argc && T_HASH == rb_type(argv[1])) { rb_hash_foreach(argv[1], append_attr, (VALUE)b); } // Do not close with > or /> yet. That is done with i_am_a_child() or pop(). if (rb_block_given_p()) { rb_yield(self); pop(b); } return Qnil; } /* call-seq: void_element(name,attributes) * * Adds an void element with the name and attributes provided. * * - +name+ - (String) name of the element * - +attributes+ - (Hash) of the element */ static VALUE builder_void_element(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); const char *name; long len; if (1 > argc) { rb_raise(ox_arg_error_class, "missing element name"); } i_am_a_child(b, false); append_indent(b); switch (rb_type(*argv)) { case T_STRING: name = StringValuePtr(*argv); len = RSTRING_LEN(*argv); break; case T_SYMBOL: name = rb_id2name(SYM2ID(*argv)); len = strlen(name); break; default: rb_raise(ox_arg_error_class, "expected a Symbol or String for an element name"); break; } buf_append(&b->buf, '<'); b->col++; b->pos++; append_string(b, name, len, xml_element_chars, false); if (1 < argc && T_HASH == rb_type(argv[1])) { rb_hash_foreach(argv[1], append_attr, (VALUE)b); } buf_append_string(&b->buf, ">", 1); b->col++; ; b->pos++; return Qnil; } /* call-seq: comment(text) * * Adds a comment element to the XML string being formed. * - +text+ - (String) contents of the comment */ static VALUE builder_comment(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "", 3); b->col += 5; b->pos += 5; return Qnil; } /* call-seq: doctype(text) * * Adds a DOCTYPE element to the XML string being formed. * - +text+ - (String) contents of the doctype */ static VALUE builder_doctype(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); rb_check_type(text, T_STRING); i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "col += 10; b->pos += 10; append_string(b, StringValuePtr(text), RSTRING_LEN(text), xml_element_chars, false); buf_append(&b->buf, '>'); b->col++; b->pos++; return Qnil; } /* call-seq: text(text) * * Adds a text element to the XML string being formed. * - +text+ - (String) contents of the text field * - +strip_invalid_chars+ - [true|false] strips any characters invalid for XML, defaults to false */ static VALUE builder_text(int argc, VALUE *argv, VALUE self) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v; volatile VALUE strip_invalid_chars; if ((0 == argc) || (argc > 2)) { rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc); } v = argv[0]; if (2 == argc) { strip_invalid_chars = argv[1]; } else { strip_invalid_chars = Qfalse; } v = rb_String(v); i_am_a_child(b, true); append_string(b, StringValuePtr(v), RSTRING_LEN(v), xml_element_chars, RTEST(strip_invalid_chars)); return Qnil; } /* call-seq: cdata(data) * * Adds a CDATA element to the XML string being formed. * - +data+ - (String) contents of the CDATA element */ static VALUE builder_cdata(VALUE self, VALUE data) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v = data; const char *str; const char *s; const char *end; int len; v = rb_String(v); str = StringValuePtr(v); len = (int)RSTRING_LEN(v); s = str; end = str + len; i_am_a_child(b, false); append_indent(b); buf_append_string(&b->buf, "col += 9; b->pos += 9; buf_append_string(&b->buf, str, len); b->col += len; s = strchr(s, '\n'); while (NULL != s) { b->line++; b->col = end - s; s = strchr(s + 1, '\n'); } b->pos += len; buf_append_string(&b->buf, "]]>", 3); b->col += 3; b->pos += 3; return Qnil; } /* call-seq: raw(text) * * Adds the provided string directly to the XML without formatting or modifications. * * - +text+ - (String) contents to be added */ static VALUE builder_raw(VALUE self, VALUE text) { Builder b = (Builder)DATA_PTR(self); volatile VALUE v = text; const char *str; const char *s; const char *end; int len; v = rb_String(v); str = StringValuePtr(v); len = (int)RSTRING_LEN(v); s = str; end = str + len; i_am_a_child(b, true); buf_append_string(&b->buf, str, len); b->col += len; s = strchr(s, '\n'); while (NULL != s) { b->line++; b->col = end - s; s = strchr(s + 1, '\n'); } b->pos += len; return Qnil; } /* call-seq: to_s() * * Returns the JSON document string in what ever state the construction is at. */ static VALUE builder_to_s(VALUE self) { return to_s((Builder)DATA_PTR(self)); } /* call-seq: line() * * Returns the current line in the output. The first line is line 1. */ static VALUE builder_line(VALUE self) { return LONG2NUM(((Builder)DATA_PTR(self))->line); } /* call-seq: column() * * Returns the current column in the output. The first character in a line is at * column 1. */ static VALUE builder_column(VALUE self) { return LONG2NUM(((Builder)DATA_PTR(self))->col); } /* call-seq: indent() * * Returns the indentation level */ static VALUE builder_get_indent(VALUE self) { return INT2NUM(((Builder)DATA_PTR(self))->indent); } /* call-seq: indent=(indent) * * Sets the indentation level * * - +indent+ (Fixnum) indentaion level, negative values excludes terminating newline */ static VALUE builder_set_indent(VALUE self, VALUE indent) { if (rb_cInteger != rb_obj_class(indent)) { rb_raise(ox_parse_error_class, "indent must be a fixnum.\n"); } ((Builder)DATA_PTR(self))->indent = NUM2INT(indent); return Qnil; } /* call-seq: pos() * * Returns the number of bytes written. */ static VALUE builder_pos(VALUE self) { return LONG2NUM(((Builder)DATA_PTR(self))->pos); } /* call-seq: pop() * * Closes the current element. */ static VALUE builder_pop(VALUE self) { pop((Builder)DATA_PTR(self)); return Qnil; } /* call-seq: close() * * Closes the all elements and the document. */ static VALUE builder_close(VALUE self) { bclose((Builder)DATA_PTR(self)); return Qnil; } /* * Document-class: Ox::Builder * * An XML builder. */ void ox_init_builder(VALUE ox) { #if 0 // Just for rdoc. ox = rb_define_module("Ox"); #endif builder_class = rb_define_class_under(ox, "Builder", rb_cObject); #if RUBY_API_VERSION_CODE >= 30200 rb_undef_alloc_func(builder_class); #endif rb_define_module_function(builder_class, "new", builder_new, -1); rb_define_module_function(builder_class, "file", builder_file, -1); rb_define_module_function(builder_class, "io", builder_io, -1); rb_define_method(builder_class, "instruct", builder_instruct, -1); rb_define_method(builder_class, "comment", builder_comment, 1); rb_define_method(builder_class, "doctype", builder_doctype, 1); rb_define_method(builder_class, "element", builder_element, -1); rb_define_method(builder_class, "void_element", builder_void_element, -1); rb_define_method(builder_class, "text", builder_text, -1); rb_define_method(builder_class, "cdata", builder_cdata, 1); rb_define_method(builder_class, "raw", builder_raw, 1); rb_define_method(builder_class, "pop", builder_pop, 0); rb_define_method(builder_class, "close", builder_close, 0); rb_define_method(builder_class, "to_s", builder_to_s, 0); rb_define_method(builder_class, "line", builder_line, 0); rb_define_method(builder_class, "column", builder_column, 0); rb_define_method(builder_class, "pos", builder_pos, 0); rb_define_method(builder_class, "indent", builder_get_indent, 0); rb_define_method(builder_class, "indent=", builder_set_indent, 1); } ox-2.14.17/ext/ox/cache.c000066400000000000000000000210361445411231300147510ustar00rootroot00000000000000// Copyright (c) 2011, 2021 Peter Ohler. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for license details. #if HAVE_PTHREAD_MUTEX_INIT #include #endif #include #include "cache.h" // The stdlib calloc, realloc, and free are used instead of the Ruby ALLOC, // ALLOC_N, REALLOC, and xfree since the later could trigger a GC which will // either corrupt memory or if the mark function locks will deadlock. #define REHASH_LIMIT 4 #define MIN_SHIFT 8 #define REUSE_MAX 8192 #if HAVE_PTHREAD_MUTEX_INIT #define CACHE_LOCK(c) pthread_mutex_lock(&((c)->mutex)) #define CACHE_UNLOCK(c) pthread_mutex_unlock(&((c)->mutex)) #else #define CACHE_LOCK(c) rb_mutex_lock((c)->mutex) #define CACHE_UNLOCK(c) rb_mutex_unlock((c)->mutex) #endif // almost the Murmur hash algorithm #define M 0x5bd1e995 typedef struct _slot { struct _slot *next; VALUE val; uint64_t hash; volatile uint32_t use_cnt; uint8_t klen; char key[CACHE_MAX_KEY]; } *Slot; typedef struct _cache { volatile Slot *slots; volatile size_t cnt; VALUE (*form)(const char *str, size_t len); uint64_t size; uint64_t mask; VALUE (*intern)(struct _cache *c, const char *key, size_t len, const char **keyp); volatile Slot reuse; size_t rcnt; #if HAVE_PTHREAD_MUTEX_INIT pthread_mutex_t mutex; #else VALUE mutex; #endif uint8_t xrate; bool mark; } *Cache; static uint64_t hash_calc(const uint8_t *key, size_t len) { const uint8_t *end = key + len; const uint8_t *endless = key + (len & 0xFFFFFFFC); uint64_t h = (uint64_t)len; uint64_t k; while (key < endless) { k = (uint64_t)*key++; k |= (uint64_t)*key++ << 8; k |= (uint64_t)*key++ << 16; k |= (uint64_t)*key++ << 24; k *= M; k ^= k >> 24; h *= M; h ^= k * M; } if (1 < end - key) { uint16_t k16 = (uint16_t)*key++; k16 |= (uint16_t)*key++ << 8; h ^= k16 << 8; } if (key < end) { h ^= *key; } h *= M; h ^= h >> 13; h *= M; h ^= h >> 15; return h; } static void rehash(Cache c) { uint64_t osize; Slot *end; Slot *sp; osize = c->size; c->size = osize * 4; c->mask = c->size - 1; c->slots = realloc((void *)c->slots, sizeof(Slot) * c->size); memset((Slot *)c->slots + osize, 0, sizeof(Slot) * osize * 3); end = (Slot *)c->slots + osize; for (sp = (Slot *)c->slots; sp < end; sp++) { Slot s = *sp; Slot next = NULL; *sp = NULL; for (; NULL != s; s = next) { uint64_t h = s->hash & c->mask; Slot *bucket = (Slot *)c->slots + h; next = s->next; s->next = *bucket; *bucket = s; } } } static VALUE ox_lockless_intern(Cache c, const char *key, size_t len, const char **keyp) { uint64_t h = hash_calc((const uint8_t *)key, len); Slot *bucket = (Slot *)c->slots + (h & c->mask); Slot b; volatile VALUE rkey; while (REUSE_MAX < c->rcnt) { if (NULL != (b = c->reuse)) { c->reuse = b->next; free(b); c->rcnt--; } else { // An accounting error occured somewhere so correct it. c->rcnt = 0; } } for (b = *bucket; NULL != b; b = b->next) { if ((uint8_t)len == b->klen && 0 == strncmp(b->key, key, len)) { b->use_cnt += 16; if (NULL != keyp) { *keyp = b->key; } return b->val; } } rkey = c->form(key, len); if (NULL == (b = c->reuse)) { b = calloc(1, sizeof(struct _slot)); } else { c->reuse = b->next; c->rcnt--; } b->hash = h; memcpy(b->key, key, len); b->klen = (uint8_t)len; b->key[len] = '\0'; b->val = rkey; b->use_cnt = 4; b->next = *bucket; *bucket = b; c->cnt++; // Don't worry about wrapping. Worse case is the entry is removed and recreated. if (NULL != keyp) { *keyp = b->key; } if (REHASH_LIMIT < c->cnt / c->size) { rehash(c); } return rkey; } static VALUE ox_locking_intern(Cache c, const char *key, size_t len, const char **keyp) { uint64_t h; Slot *bucket; Slot b; uint64_t old_size; volatile VALUE rkey; CACHE_LOCK(c); while (REUSE_MAX < c->rcnt) { if (NULL != (b = c->reuse)) { c->reuse = b->next; free(b); c->rcnt--; } else { // An accounting error occured somewhere so correct it. c->rcnt = 0; } } h = hash_calc((const uint8_t *)key, len); bucket = (Slot *)c->slots + (h & c->mask); for (b = *bucket; NULL != b; b = b->next) { if ((uint8_t)len == b->klen && 0 == strncmp(b->key, key, len)) { b->use_cnt += 4; if (NULL != keyp) { *keyp = b->key; } CACHE_UNLOCK(c); return b->val; } } old_size = c->size; // The creation of a new value may trigger a GC which be a problem if the // cache is locked so make sure it is unlocked for the key value creation. if (NULL != (b = c->reuse)) { c->reuse = b->next; c->rcnt--; } CACHE_UNLOCK(c); if (NULL == b) { b = calloc(1, sizeof(struct _slot)); } rkey = c->form(key, len); b->hash = h; memcpy(b->key, key, len); b->klen = (uint8_t)len; b->key[len] = '\0'; b->val = rkey; b->use_cnt = 16; // Lock again to add the new entry. CACHE_LOCK(c); if (old_size != c->size) { h = hash_calc((const uint8_t *)key, len); bucket = (Slot *)c->slots + (h & c->mask); } b->next = *bucket; *bucket = b; c->cnt++; // Don't worry about wrapping. Worse case is the entry is removed and recreated. if (NULL != keyp) { *keyp = b->key; } if (REHASH_LIMIT < c->cnt / c->size) { rehash(c); } CACHE_UNLOCK(c); return rkey; } Cache ox_cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking) { Cache c = calloc(1, sizeof(struct _cache)); int shift = 0; for (; REHASH_LIMIT < size; size /= 2, shift++) { } if (shift < MIN_SHIFT) { shift = MIN_SHIFT; } #if HAVE_PTHREAD_MUTEX_INIT pthread_mutex_init(&c->mutex, NULL); #else c->mutex = rb_mutex_new(); #endif c->size = 1 << shift; c->mask = c->size - 1; c->slots = calloc(c->size, sizeof(Slot)); c->form = form; c->xrate = 1; // low c->mark = mark; if (locking) { c->intern = ox_locking_intern; } else { c->intern = ox_lockless_intern; } return c; } void ox_cache_free(Cache c) { uint64_t i; for (i = 0; i < c->size; i++) { Slot next; Slot s; for (s = c->slots[i]; NULL != s; s = next) { next = s->next; free(s); } } free((void *)c->slots); free(c); } void ox_cache_mark(Cache c) { uint64_t i; #if !HAVE_PTHREAD_MUTEX_INIT rb_gc_mark(c->mutex); #endif if (0 == c->cnt) { return; } for (i = 0; i < c->size; i++) { Slot s; Slot prev = NULL; Slot next; for (s = c->slots[i]; NULL != s; s = next) { next = s->next; if (0 == s->use_cnt) { if (NULL == prev) { c->slots[i] = next; } else { prev->next = next; } c->cnt--; s->next = c->reuse; c->reuse = s; c->rcnt++; continue; } switch (c->xrate) { case 0: break; case 2: s->use_cnt -= 2; break; case 3: s->use_cnt /= 2; break; default: s->use_cnt--; break; } if (c->mark) { rb_gc_mark(s->val); } prev = s; } } } VALUE ox_cache_intern(Cache c, const char *key, size_t len, const char **keyp) { if (CACHE_MAX_KEY <= len) { if (NULL != keyp) { volatile VALUE rkey = c->form(key, len); if (SYMBOL_P(rkey)) { *keyp = rb_id2name(rb_sym2id(rkey)); } return rkey; } return c->form(key, len); } return c->intern(c, key, len, keyp); } ox-2.14.17/ext/ox/cache.h000066400000000000000000000011701445411231300147530ustar00rootroot00000000000000// Copyright (c) 2021 Peter Ohler. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for license details. #ifndef OX_CACHE_H #define OX_CACHE_H #include #include #define CACHE_MAX_KEY 35 struct _cache; extern struct _cache *ox_cache_create(size_t size, VALUE (*form)(const char *str, size_t len), bool mark, bool locking); extern void ox_cache_free(struct _cache *c); extern void ox_cache_mark(struct _cache *c); extern VALUE ox_cache_intern(struct _cache *c, const char *key, size_t len, const char **keyp); #endif /* OX_CACHE_H */ ox-2.14.17/ext/ox/cache8.c000066400000000000000000000042741445411231300150460ustar00rootroot00000000000000/* cache8.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "cache8.h" #include #include #include #include #include #include "ruby.h" #define BITS 4 #define MASK 0x000000000000000FULL #define SLOT_CNT 16 #define DEPTH 16 typedef union { struct _cache8 *child; slot_t value; } Bucket; struct _cache8 { Bucket buckets[SLOT_CNT]; }; static void cache8_delete(Cache8 cache, int depth); // static void slot_print(Cache8 cache, sid_t key, unsigned int depth); void ox_cache8_new(Cache8 *cache) { Bucket *b; int i; *cache = ALLOC(struct _cache8); for (i = SLOT_CNT, b = (*cache)->buckets; 0 < i; i--, b++) { b->value = 0; } } void ox_cache8_delete(Cache8 cache) { cache8_delete(cache, 0); } static void cache8_delete(Cache8 cache, int depth) { Bucket *b; unsigned int i; for (i = 0, b = cache->buckets; i < SLOT_CNT; i++, b++) { if (0 != b->child) { if (DEPTH - 1 != depth) { cache8_delete(b->child, depth + 1); } } } xfree(cache); } slot_t ox_cache8_get(Cache8 cache, sid_t key, slot_t **slot) { Bucket *b; int i; sid_t k8 = (sid_t)key; sid_t k; for (i = 64 - BITS; 0 < i; i -= BITS) { k = (k8 >> i) & MASK; b = cache->buckets + k; if (0 == b->child) { ox_cache8_new(&b->child); } cache = b->child; } *slot = &(cache->buckets + (k8 & MASK))->value; return **slot; } #if 0 void ox_cache8_print(Cache8 cache) { //printf("-------------------------------------------\n"); slot_print(cache, 0, 0); } static void slot_print(Cache8 c, sid_t key, unsigned int depth) { Bucket *b; unsigned int i; sid_t k8 = (sid_t)key; sid_t k; for (i = 0, b = c->buckets; i < SLOT_CNT; i++, b++) { if (0 != b->child) { k = (k8 << BITS) | i; //printf("*** key: 0x%016llx depth: %u i: %u\n", k, depth, i); if (DEPTH - 1 == depth) { printf("0x%016llx: %4llu\n", (unsigned long long)k, (unsigned long long)b->value); } else { slot_print(b->child, k, depth + 1); } } } } #endif ox-2.14.17/ext/ox/cache8.h000066400000000000000000000007411445411231300150460ustar00rootroot00000000000000/* cache8.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_CACHE8_H #define OX_CACHE8_H #include "ruby.h" #include "stdint.h" typedef struct _cache8 *Cache8; typedef uint64_t slot_t; typedef uint64_t sid_t; extern void ox_cache8_new(Cache8 *cache); extern void ox_cache8_delete(Cache8 cache); extern slot_t ox_cache8_get(Cache8 cache, sid_t key, slot_t **slot); // extern void ox_cache8_print(Cache8 cache); #endif /* OX_CACHE8_H */ ox-2.14.17/ext/ox/dump.c000066400000000000000000001112301445411231300146470ustar00rootroot00000000000000/* dump.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include "base64.h" #include "cache8.h" #include "ox.h" #define USE_B64 0 #define MAX_DEPTH 1000 typedef unsigned long ulong; typedef struct _str { const char *str; size_t len; } *Str; typedef struct _element { struct _str clas; struct _str attr; unsigned long id; int indent; /* < 0 indicates no \n */ int closed; char type; } *Element; typedef struct _out { void (*w_start)(struct _out *out, Element e); void (*w_end)(struct _out *out, Element e); void (*w_time)(struct _out *out, VALUE obj); char *buf; char *end; char *cur; Cache8 circ_cache; unsigned long circ_cnt; int indent; int depth; /* used by dumpHash */ Options opts; VALUE obj; } *Out; static void dump_obj_to_xml(VALUE obj, Options copts, Out out); static void dump_first_obj(VALUE obj, Out out); static void dump_obj(ID aid, VALUE obj, int depth, Out out); static void dump_gen_doc(VALUE obj, int depth, Out out); static void dump_gen_element(VALUE obj, int depth, Out out); static void dump_gen_instruct(VALUE obj, int depth, Out out); static int dump_gen_attr(VALUE key, VALUE value, VALUE ov); static int dump_gen_nodes(VALUE obj, int depth, Out out); static void dump_gen_val_node(VALUE obj, int depth, const char *pre, size_t plen, const char *suf, size_t slen, Out out); static void dump_start(Out out, Element e); static void dump_end(Out out, Element e); static void grow(Out out, size_t len); static void dump_value(Out out, const char *value, size_t size); static void dump_str_value(Out out, const char *value, size_t size, const char *table); static int dump_var(ID key, VALUE value, VALUE ov); static void dump_num(Out out, VALUE obj); static void dump_date(Out out, VALUE obj); static void dump_time_thin(Out out, VALUE obj); static void dump_time_xsd(Out out, VALUE obj); static int dump_hash(VALUE key, VALUE value, VALUE ov); static int is_xml_friendly(const uchar *str, int len, const char *table); static const char hex_chars[17] = "0123456789abcdef"; // The : character is equivalent to 10. Used for replacement characters up to 10 // characters long such as '􏿿'. static const char xml_friendly_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11611156111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; static const char xml_quote_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11611151111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; static const char xml_element_chars[257] = "\ :::::::::11::1::::::::::::::::::\ 11111151111111111111111111114141\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111\ 11111111111111111111111111111111"; inline static int is_xml_friendly(const uchar *str, int len, const char *table) { for (; 0 < len; str++, len--) { if ('1' != table[*str]) { return 0; } } return 1; } inline static size_t xml_str_len(const uchar *str, size_t len, const char *table) { size_t size = 0; for (; 0 < len; str++, len--) { size += xml_friendly_chars[*str]; } return size - len * (size_t)'0'; } inline static void dump_hex(uchar c, Out out) { uchar d = (c >> 4) & 0x0F; *out->cur++ = hex_chars[d]; d = c & 0x0F; *out->cur++ = hex_chars[d]; } static Type obj_class_code(VALUE obj) { VALUE clas = rb_obj_class(obj); switch (rb_type(obj)) { case T_NIL: return NilClassCode; case T_ARRAY: return ArrayCode; case T_HASH: return HashCode; case T_TRUE: return TrueClassCode; case T_FALSE: return FalseClassCode; case T_FIXNUM: return FixnumCode; case T_FLOAT: return FloatCode; case T_STRING: return (is_xml_friendly((uchar *)StringValuePtr(obj), (int)RSTRING_LEN(obj), xml_element_chars)) ? StringCode : String64Code; case T_SYMBOL: { const char *sym = rb_id2name(SYM2ID(obj)); return (is_xml_friendly((uchar *)sym, (int)strlen(sym), xml_element_chars)) ? SymbolCode : Symbol64Code; } case T_DATA: return (rb_cTime == clas) ? TimeCode : ((ox_date_class == clas) ? DateCode : 0); case T_STRUCT: return (rb_cRange == clas) ? RangeCode : StructCode; case T_OBJECT: return (ox_document_clas == clas || ox_element_clas == clas) ? RawCode : ObjectCode; case T_REGEXP: return RegexpCode; case T_BIGNUM: return BignumCode; case T_COMPLEX: return ComplexCode; case T_RATIONAL: return RationalCode; case T_CLASS: return ClassCode; default: return 0; } } inline static void fill_indent(Out out, int cnt) { if (0 <= cnt) { *out->cur++ = '\n'; if (0 < out->opts->margin_len) { memcpy(out->cur, out->opts->margin, out->opts->margin_len); out->cur += out->opts->margin_len; } for (; 0 < cnt; cnt--) { *out->cur++ = ' '; } } } inline static void fill_value(Out out, const char *value, size_t len) { if (6 < len) { memcpy(out->cur, value, len); out->cur += len; } else { for (; 0 < len; len--, value++) { *out->cur++ = *value; } } } inline static void fill_attr(Out out, char name, const char *value, size_t len) { *out->cur++ = ' '; *out->cur++ = name; *out->cur++ = '='; *out->cur++ = '"'; if (6 < len) { memcpy(out->cur, value, len); out->cur += len; } else { for (; 0 < len; len--, value++) { *out->cur++ = *value; } } *out->cur++ = '"'; } inline static const char *ulong2str(ulong num, char *end) { char *b; *end-- = '\0'; for (b = end; 0 < num || b == end; num /= 10, b--) { *b = (num % 10) + '0'; } b++; return b; } static int check_circular(Out out, VALUE obj, Element e) { slot_t *slot; slot_t id; int result; if (0 == (id = ox_cache8_get(out->circ_cache, obj, &slot))) { out->circ_cnt++; id = out->circ_cnt; *slot = id; e->id = id; result = 0; } else { e->type = RefCode; e->clas.len = 0; e->clas.str = 0; e->closed = 1; e->id = id; out->w_start(out, e); result = 1; } return result; } static void grow(Out out, size_t len) { size_t size = out->end - out->buf; long pos = out->cur - out->buf; size *= 2; if (size <= len * 2 + pos) { size += len; } REALLOC_N(out->buf, char, size + 10); /* 10 extra for terminator character plus extra (paranoid) */ out->end = out->buf + size; out->cur = out->buf + pos; } static void dump_start(Out out, Element e) { size_t size = e->indent + 4 + out->opts->margin_len; if (0 < e->attr.len) { /* a="attr" */ size += e->attr.len + 5; } if (0 < e->clas.len) { /* c="class" */ size += e->clas.len + 5; } if (0 < e->id) { /* i="id" */ size += 24; /* over estimate, 19 digits */ } if (out->end - out->cur <= (long)size) { grow(out, size); } if (out->buf + out->opts->margin_len < out->cur) { fill_indent(out, e->indent); } *out->cur++ = '<'; *out->cur++ = e->type; if (0 < e->attr.len) { fill_attr(out, 'a', e->attr.str, e->attr.len); } if ((ObjectCode == e->type || ExceptionCode == e->type || StructCode == e->type || ClassCode == e->type) && 0 < e->clas.len) { fill_attr(out, 'c', e->clas.str, e->clas.len); } if (0 < e->id) { char buf[32]; char *end = buf + sizeof(buf) - 1; const char *s = ulong2str(e->id, end); fill_attr(out, 'i', s, end - s); } if (e->closed) { if (out->opts->no_empty) { *out->cur++ = '>'; *out->cur++ = '<'; *out->cur++ = '/'; *out->cur++ = e->type; } else { *out->cur++ = '/'; } } *out->cur++ = '>'; *out->cur = '\0'; } static void dump_end(Out out, Element e) { size_t size = e->indent + 5 + out->opts->margin_len; if (out->end - out->cur <= (long)size) { grow(out, size); } fill_indent(out, e->indent); *out->cur++ = '<'; *out->cur++ = '/'; *out->cur++ = e->type; *out->cur++ = '>'; *out->cur = '\0'; } inline static void dump_value(Out out, const char *value, size_t size) { if (out->end - out->cur <= (long)size) { grow(out, size); } if (6 < size) { memcpy(out->cur, value, size); out->cur += size; } else { for (; 0 < size; size--, value++) { *out->cur++ = *value; } } *out->cur = '\0'; } inline static void dump_str_value(Out out, const char *value, size_t size, const char *table) { size_t xsize = xml_str_len((const uchar *)value, size, table); if (out->end - out->cur <= (long)xsize) { grow(out, xsize); } for (; 0 < size; size--, value++) { if ('1' == table[(uchar)*value]) { *out->cur++ = *value; } else { switch (*value) { case '"': *out->cur++ = '&'; *out->cur++ = 'q'; *out->cur++ = 'u'; *out->cur++ = 'o'; *out->cur++ = 't'; *out->cur++ = ';'; break; case '&': *out->cur++ = '&'; *out->cur++ = 'a'; *out->cur++ = 'm'; *out->cur++ = 'p'; *out->cur++ = ';'; break; case '\'': *out->cur++ = '&'; *out->cur++ = 'a'; *out->cur++ = 'p'; *out->cur++ = 'o'; *out->cur++ = 's'; *out->cur++ = ';'; break; case '<': *out->cur++ = '&'; *out->cur++ = 'l'; *out->cur++ = 't'; *out->cur++ = ';'; break; case '>': *out->cur++ = '&'; *out->cur++ = 'g'; *out->cur++ = 't'; *out->cur++ = ';'; break; default: // Must be one of the invalid characters. if (StrictEffort == out->opts->effort) { rb_raise(ox_syntax_error_class, "'\\#x%02x' is not a valid XML character.", *value); } if (Yes == out->opts->allow_invalid) { *out->cur++ = '&'; *out->cur++ = '#'; *out->cur++ = 'x'; *out->cur++ = '0'; *out->cur++ = '0'; dump_hex(*value, out); *out->cur++ = ';'; } else if ('\0' != *out->opts->inv_repl) { // If the empty string then ignore. The first character of // the replacement is the length. memcpy(out->cur, out->opts->inv_repl + 1, (size_t)*out->opts->inv_repl); out->cur += *out->opts->inv_repl; } break; } } } *out->cur = '\0'; } inline static void dump_num(Out out, VALUE obj) { char buf[32]; char *b = buf + sizeof(buf) - 1; long num = NUM2LONG(obj); int neg = 0; if (0 > num) { neg = 1; num = -num; } *b-- = '\0'; if (0 < num) { for (; 0 < num; num /= 10, b--) { *b = (num % 10) + '0'; } if (neg) { *b = '-'; } else { b++; } } else { *b = '0'; } if (out->end - out->cur <= (long)(sizeof(buf) - (b - buf))) { grow(out, sizeof(buf) - (b - buf)); } for (; '\0' != *b; b++) { *out->cur++ = *b; } *out->cur = '\0'; } static void dump_time_thin(Out out, VALUE obj) { char buf[64]; char *b = buf + sizeof(buf) - 1; struct timespec ts = rb_time_timespec(obj); time_t sec = ts.tv_sec; long nsec = ts.tv_nsec; char *dot = b - 10; long size; *b-- = '\0'; for (; dot < b; b--, nsec /= 10) { *b = '0' + (nsec % 10); } *b-- = '.'; for (; 0 < sec; b--, sec /= 10) { *b = '0' + (sec % 10); } b++; size = sizeof(buf) - (b - buf) - 1; if (out->end - out->cur <= size) { grow(out, size); } memcpy(out->cur, b, size); out->cur += size; } static void dump_date(Out out, VALUE obj) { char buf[64]; char *b = buf + sizeof(buf) - 1; long jd = NUM2LONG(rb_funcall2(obj, ox_jd_id, 0, 0)); long size; *b-- = '\0'; for (; 0 < jd; b--, jd /= 10) { *b = '0' + (jd % 10); } b++; if ('\0' == *b) { b--; *b = '0'; } size = sizeof(buf) - (b - buf) - 1; if (out->end - out->cur <= size) { grow(out, size); } memcpy(out->cur, b, size); out->cur += size; } static void dump_time_xsd(Out out, VALUE obj) { struct tm *tm; struct timespec ts = rb_time_timespec(obj); time_t sec = ts.tv_sec; long nsec = ts.tv_nsec; int tzhour, tzmin; char tzsign = '+'; if (out->end - out->cur <= 33) { grow(out, 33); } /* 2010-07-09T10:47:45.895826+09:00 */ tm = localtime(&sec); #if HAVE_ST_TM_GMTOFF if (0 > tm->tm_gmtoff) { tzsign = '-'; tzhour = (int)(tm->tm_gmtoff / -3600); tzmin = (int)(tm->tm_gmtoff / -60) - (tzhour * 60); } else { tzhour = (int)(tm->tm_gmtoff / 3600); tzmin = (int)(tm->tm_gmtoff / 60) - (tzhour * 60); } #else tzhour = 0; tzmin = 0; #endif /* TBD replace with more efficient printer */ out->cur += sprintf(out->cur, "%04d-%02d-%02dT%02d:%02d:%02d.%06ld%c%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, nsec / 1000, tzsign, tzhour, tzmin); } static void dump_first_obj(VALUE obj, Out out) { char buf[128]; Options copts = out->opts; int cnt; if (Yes == copts->with_xml) { if (0 < copts->margin_len) { dump_value(out, copts->margin, copts->margin_len); } if ('\0' == *copts->encoding) { dump_value(out, "", 21); } else { cnt = snprintf(buf, sizeof(buf), "", copts->encoding); dump_value(out, buf, cnt); } } if (Yes == copts->with_instruct) { if (out->buf < out->cur) { dump_value(out, "\n", 1); } if (0 < copts->margin_len) { dump_value(out, copts->margin, copts->margin_len); } cnt = snprintf( buf, sizeof(buf), "", (Yes == copts->circular) ? " circular=\"yes\"" : ((No == copts->circular) ? " circular=\"no\"" : ""), (Yes == copts->xsd_date) ? " xsd_date=\"yes\"" : ((No == copts->xsd_date) ? " xsd_date=\"no\"" : "")); dump_value(out, buf, cnt); } if (Yes == copts->with_dtd) { if (0 < copts->margin_len) { dump_value(out, copts->margin, copts->margin_len); } cnt = snprintf(buf, sizeof(buf), "%s", (out->buf < out->cur) ? "\n" : "", obj_class_code(obj)); dump_value(out, buf, cnt); } if (0 < copts->margin_len) { dump_value(out, copts->margin, copts->margin_len); } dump_obj(0, obj, 0, out); } static void dump_obj(ID aid, VALUE obj, int depth, Out out) { struct _element e; VALUE prev_obj = out->obj; char value_buf[64]; int cnt; if (MAX_DEPTH < depth) { rb_raise(rb_eSysStackError, "maximum depth exceeded"); } out->obj = obj; if (0 == aid) { e.attr.str = 0; e.attr.len = 0; } else { e.attr.str = rb_id2name(aid); // Ruby 2.3 started to return NULL for some IDs so check for // NULL. Ignore if NULL aid. if (NULL == e.attr.str) { return; } e.attr.len = strlen(e.attr.str); } e.closed = 0; if (0 == depth) { e.indent = (0 <= out->indent) ? 0 : -1; } else if (0 > out->indent) { e.indent = -1; } else if (0 == out->indent) { e.indent = 0; } else { e.indent = depth * out->indent; } e.id = 0; e.clas.len = 0; e.clas.str = 0; switch (rb_type(obj)) { case T_NIL: e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); break; case T_ARRAY: if (0 != out->circ_cache && check_circular(out, obj, &e)) { break; } cnt = (int)RARRAY_LEN(obj); e.type = ArrayCode; e.closed = (0 >= cnt); out->w_start(out, &e); if (!e.closed) { const VALUE *np = RARRAY_PTR(obj); int i; int d2 = depth + 1; for (i = cnt; 0 < i; i--, np++) { dump_obj(0, *np, d2, out); } out->w_end(out, &e); } break; case T_HASH: if (0 != out->circ_cache && check_circular(out, obj, &e)) { break; } cnt = (int)RHASH_SIZE(obj); e.type = HashCode; e.closed = (0 >= cnt); out->w_start(out, &e); if (0 < cnt) { unsigned int od = out->depth; out->depth = depth + 1; rb_hash_foreach(obj, dump_hash, (VALUE)out); out->depth = od; out->w_end(out, &e); } break; case T_TRUE: e.type = TrueClassCode; e.closed = 1; out->w_start(out, &e); break; case T_FALSE: e.type = FalseClassCode; e.closed = 1; out->w_start(out, &e); break; case T_FIXNUM: e.type = FixnumCode; out->w_start(out, &e); dump_num(out, obj); e.indent = -1; out->w_end(out, &e); break; case T_FLOAT: e.type = FloatCode; cnt = snprintf(value_buf, sizeof(value_buf), "%0.16g", rb_num2dbl(obj)); out->w_start(out, &e); dump_value(out, value_buf, cnt); e.indent = -1; out->w_end(out, &e); break; case T_STRING: { const char *str; if (0 != out->circ_cache && check_circular(out, obj, &e)) { break; } str = StringValuePtr(obj); cnt = (int)RSTRING_LEN(obj); #if USE_B64 if (is_xml_friendly((uchar *)str, cnt)) { e.type = StringCode; out->w_start(out, &e); dump_str_value(out, str, cnt, '<'); e.indent = -1; out->w_end(out, &e); } else { ulong size = b64_size(cnt); char *b64 = ALLOCA_N(char, size + 1); e.type = String64Code; to_base64((uchar *)str, cnt, b64); out->w_start(out, &e); dump_value(out, b64, size); e.indent = -1; out->w_end(out, &e); } #else e.type = StringCode; out->w_start(out, &e); dump_str_value(out, str, cnt, xml_element_chars); e.indent = -1; out->w_end(out, &e); #endif break; } case T_SYMBOL: { const char *sym = rb_id2name(SYM2ID(obj)); cnt = (int)strlen(sym); #if USE_B64 if (is_xml_friendly((uchar *)sym, cnt)) { e.type = SymbolCode; out->w_start(out, &e); dump_str_value(out, sym, cnt, '<'); e.indent = -1; out->w_end(out, &e); } else { ulong size = b64_size(cnt); char *b64 = ALLOCA_N(char, size + 1); e.type = Symbol64Code; to_base64((uchar *)sym, cnt, b64); out->w_start(out, &e); dump_value(out, b64, size); e.indent = -1; out->w_end(out, &e); } #else e.type = SymbolCode; out->w_start(out, &e); dump_str_value(out, sym, cnt, xml_element_chars); e.indent = -1; out->w_end(out, &e); #endif break; } case T_DATA: { VALUE clas; clas = rb_obj_class(obj); if (rb_cTime == clas) { e.type = TimeCode; out->w_start(out, &e); out->w_time(out, obj); e.indent = -1; out->w_end(out, &e); } else { const char *classname = rb_class2name(clas); if (0 == strcmp("Date", classname)) { e.type = DateCode; out->w_start(out, &e); dump_date(out, obj); e.indent = -1; out->w_end(out, &e); } else if (0 == strcmp("BigDecimal", classname)) { volatile VALUE rs = rb_String(obj); e.type = BigDecimalCode; out->w_start(out, &e); dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs)); e.indent = -1; out->w_end(out, &e); } else { if (StrictEffort == out->opts->effort) { rb_raise(rb_eNotImpError, "Failed to dump T_DATA %s\n", classname); } else { e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); } } } break; } case T_STRUCT: { #ifdef RSTRUCT_GET VALUE clas; if (0 != out->circ_cache && check_circular(out, obj, &e)) { break; } clas = rb_obj_class(obj); if (rb_cRange == clas) { VALUE beg = RSTRUCT_GET(obj, 0); VALUE end = RSTRUCT_GET(obj, 1); VALUE excl = RSTRUCT_GET(obj, 2); int d2 = depth + 1; e.type = RangeCode; e.clas.len = 5; e.clas.str = "Range"; out->w_start(out, &e); dump_obj(ox_beg_id, beg, d2, out); dump_obj(ox_end_id, end, d2, out); dump_obj(ox_excl_id, excl, d2, out); out->w_end(out, &e); } else { char num_buf[16]; int d2 = depth + 1; long i; long cnt = NUM2LONG(rb_struct_size(obj)); e.type = StructCode; e.clas.str = rb_class2name(clas); e.clas.len = strlen(e.clas.str); out->w_start(out, &e); for (i = 0; i < cnt; i++) { VALUE v = RSTRUCT_GET(obj, (int)(i)); dump_obj(rb_intern(ulong2str(i, num_buf + sizeof(num_buf) - 1)), v, d2, out); } out->w_end(out, &e); } #else e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); #endif break; } case T_OBJECT: { VALUE clas; if (0 != out->circ_cache && check_circular(out, obj, &e)) { break; } clas = rb_obj_class(obj); e.clas.str = rb_class2name(clas); e.clas.len = strlen(e.clas.str); if (ox_document_clas == clas) { e.type = RawCode; out->w_start(out, &e); dump_gen_doc(obj, depth + 1, out); out->w_end(out, &e); } else if (ox_element_clas == clas) { e.type = RawCode; out->w_start(out, &e); dump_gen_element(obj, depth + 1, out); out->w_end(out, &e); } else { /* Object */ e.type = (Qtrue == rb_obj_is_kind_of(obj, rb_eException)) ? ExceptionCode : ObjectCode; cnt = (int)rb_ivar_count(obj); e.closed = (0 >= cnt); out->w_start(out, &e); if (0 < cnt) { unsigned int od = out->depth; out->depth = depth + 1; rb_ivar_foreach(obj, dump_var, (VALUE)out); out->depth = od; out->w_end(out, &e); } } break; } case T_REGEXP: { volatile VALUE rs = rb_funcall2(obj, ox_inspect_id, 0, 0); const char *s = StringValuePtr(rs); cnt = (int)RSTRING_LEN(rs); e.type = RegexpCode; out->w_start(out, &e); #if USE_B64 if (is_xml_friendly((uchar *)s, cnt)) { /*dump_value(out, "/", 1); */ dump_str_value(out, s, cnt, '<'); } else { ulong size = b64_size(cnt); char *b64 = ALLOCA_N(char, size + 1); to_base64((uchar *)s, cnt, b64); dump_value(out, b64, size); } #else dump_str_value(out, s, cnt, xml_element_chars); #endif e.indent = -1; out->w_end(out, &e); break; } case T_BIGNUM: { volatile VALUE rs = rb_big2str(obj, 10); e.type = BignumCode; out->w_start(out, &e); dump_value(out, StringValuePtr(rs), RSTRING_LEN(rs)); e.indent = -1; out->w_end(out, &e); break; } case T_COMPLEX: e.type = ComplexCode; out->w_start(out, &e); #ifdef RCOMPLEX dump_obj(0, RCOMPLEX(obj)->real, depth + 1, out); dump_obj(0, RCOMPLEX(obj)->imag, depth + 1, out); #else dump_obj(0, rb_funcall2(obj, rb_intern("real"), 0, 0), depth + 1, out); dump_obj(0, rb_funcall2(obj, rb_intern("imag"), 0, 0), depth + 1, out); #endif out->w_end(out, &e); break; case T_RATIONAL: e.type = RationalCode; out->w_start(out, &e); #ifdef RRATIONAL dump_obj(0, RRATIONAL(obj)->num, depth + 1, out); dump_obj(0, RRATIONAL(obj)->den, depth + 1, out); #else dump_obj(0, rb_funcall2(obj, rb_intern("numerator"), 0, 0), depth + 1, out); dump_obj(0, rb_funcall2(obj, rb_intern("denominator"), 0, 0), depth + 1, out); #endif out->w_end(out, &e); break; case T_CLASS: { e.type = ClassCode; e.clas.str = rb_class2name(obj); e.clas.len = strlen(e.clas.str); e.closed = 1; out->w_start(out, &e); break; } default: if (StrictEffort == out->opts->effort) { rb_raise(rb_eNotImpError, "Failed to dump %s Object (%02x)\n", rb_obj_classname(obj), rb_type(obj)); } else { e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); } break; } out->obj = prev_obj; } static int dump_var(ID key, VALUE value, VALUE ov) { Out out = (Out)ov; if (T_DATA == rb_type(value) && key == ox_mesg_id) { /* There is a secret recipe that keeps Exception mesg attributes as a * T_DATA until it is needed. The safe way around this hack is to call * the message() method and use the returned string as the * message. Not pretty but it solves the most common use of this * hack. If there are others they will have to be handled one at a * time. */ value = rb_funcall(out->obj, ox_message_id, 0); } dump_obj(key, value, out->depth, out); return ST_CONTINUE; } static int dump_hash(VALUE key, VALUE value, VALUE ov) { Out out = (Out)ov; dump_obj(0, key, out->depth, out); dump_obj(0, value, out->depth, out); return ST_CONTINUE; } static void dump_gen_doc(VALUE obj, int depth, Out out) { volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id); volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id); if ('\0' == *out->opts->encoding && Qnil != attrs) { volatile VALUE renc = rb_hash_lookup(attrs, ox_encoding_sym); if (Qnil != renc) { const char *enc = StringValuePtr(renc); strncpy(out->opts->encoding, enc, sizeof(out->opts->encoding) - 1); } } if (Yes == out->opts->with_xml) { if (0 < out->opts->margin_len) { dump_value(out, out->opts->margin, out->opts->margin_len); } dump_value(out, "", 2); } if (Yes == out->opts->with_instruct) { if (out->buf < out->cur) { dump_value(out, "\n", 1); } if (0 < out->opts->margin_len) { dump_value(out, out->opts->margin, out->opts->margin_len); } dump_value(out, "", 35); } if (Qnil != nodes) { dump_gen_nodes(nodes, depth, out); } } static void dump_gen_element(VALUE obj, int depth, Out out) { volatile VALUE rname = rb_attr_get(obj, ox_at_value_id); volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id); volatile VALUE nodes = rb_attr_get(obj, ox_nodes_id); const char *name = StringValuePtr(rname); long nlen = RSTRING_LEN(rname); size_t size; int indent; if (0 > out->indent) { indent = -1; } else if (0 == out->indent) { indent = 0; } else { indent = depth * out->indent; } size = indent + 4 + nlen + out->opts->margin_len; if (out->end - out->cur <= (long)size) { grow(out, size); } if (0 == depth && 0 < out->opts->margin_len && 0 < out->indent) { memcpy(out->cur, out->opts->margin, out->opts->margin_len); out->cur += out->opts->margin_len; } fill_indent(out, indent); *out->cur++ = '<'; fill_value(out, name, nlen); if (Qnil != attrs) { rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out); } if (Qnil != nodes && 0 < RARRAY_LEN(nodes)) { int do_indent; *out->cur++ = '>'; do_indent = dump_gen_nodes(nodes, depth, out); if (out->end - out->cur <= (long)size) { grow(out, size); } if (do_indent) { fill_indent(out, indent); } *out->cur++ = '<'; *out->cur++ = '/'; fill_value(out, name, nlen); } else if (out->opts->no_empty) { *out->cur++ = '>'; *out->cur++ = '<'; *out->cur++ = '/'; fill_value(out, name, nlen); } else { *out->cur++ = '/'; } *out->cur++ = '>'; *out->cur = '\0'; } static void dump_gen_instruct(VALUE obj, int depth, Out out) { volatile VALUE rname = rb_attr_get(obj, ox_at_value_id); volatile VALUE attrs = rb_attr_get(obj, ox_attributes_id); volatile VALUE rcontent = rb_attr_get(obj, ox_at_content_id); const char *name = StringValuePtr(rname); const char *content = 0; long nlen = RSTRING_LEN(rname); long clen = 0; size_t size; if (T_STRING == rb_type(rcontent)) { content = StringValuePtr(rcontent); clen = RSTRING_LEN(rcontent); size = 4 + nlen + clen; } else { size = 4 + nlen; } if (out->end - out->cur <= (long)size) { grow(out, size); } *out->cur++ = '<'; *out->cur++ = '?'; fill_value(out, name, nlen); if (0 != content) { fill_value(out, content, clen); } else if (Qnil != attrs) { rb_hash_foreach(attrs, dump_gen_attr, (VALUE)out); } *out->cur++ = '?'; *out->cur++ = '>'; *out->cur = '\0'; } static int dump_gen_nodes(VALUE obj, int depth, Out out) { long cnt = RARRAY_LEN(obj); int indent_needed = 1; if (0 < cnt) { const VALUE *np = RARRAY_PTR(obj); VALUE clas; int d2 = depth + 1; if (MAX_DEPTH < depth) { rb_raise(rb_eSysStackError, "maximum depth exceeded"); } for (; 0 < cnt; cnt--, np++) { clas = rb_obj_class(*np); if (ox_element_clas == clas) { dump_gen_element(*np, d2, out); } else if (ox_instruct_clas == clas) { dump_gen_instruct(*np, d2, out); indent_needed = (1 == cnt) ? 0 : 1; } else if (rb_cString == clas) { dump_str_value(out, StringValuePtr(*(VALUE *)np), RSTRING_LEN(*np), xml_element_chars); indent_needed = (1 == cnt) ? 0 : 1; } else if (ox_comment_clas == clas) { dump_gen_val_node(*np, d2, "", 4, out); } else if (ox_raw_clas == clas) { dump_gen_val_node(*np, d2, "", 0, "", 0, out); } else if (ox_cdata_clas == clas) { dump_gen_val_node(*np, d2, "", 3, out); } else if (ox_doctype_clas == clas) { dump_gen_val_node(*np, d2, "", 1, out); } else { rb_raise(rb_eTypeError, "Unexpected class, %s, while dumping generic XML\n", rb_class2name(clas)); } } } return indent_needed; } static int dump_gen_attr(VALUE key, VALUE value, VALUE ov) { Out out = (Out)ov; const char *ks; size_t klen; size_t size; switch (rb_type(key)) { case T_SYMBOL: ks = rb_id2name(SYM2ID(key)); break; case T_STRING: ks = StringValuePtr(key); break; default: key = rb_String(key); ks = StringValuePtr(key); break; } klen = strlen(ks); value = rb_String(value); size = 4 + klen + RSTRING_LEN(value); if (out->end - out->cur <= (long)size) { grow(out, size); } *out->cur++ = ' '; fill_value(out, ks, klen); *out->cur++ = '='; *out->cur++ = '"'; dump_str_value(out, StringValuePtr(value), RSTRING_LEN(value), xml_quote_chars); *out->cur++ = '"'; return ST_CONTINUE; } static void dump_gen_val_node(VALUE obj, int depth, const char *pre, size_t plen, const char *suf, size_t slen, Out out) { volatile VALUE v = rb_attr_get(obj, ox_at_value_id); const char *val; size_t vlen; size_t size; int indent; if (T_STRING != rb_type(v)) { return; } val = StringValuePtr(v); vlen = RSTRING_LEN(v); if (0 > out->indent) { indent = -1; } else if (0 == out->indent) { indent = 0; } else { indent = depth * out->indent; } size = indent + plen + slen + vlen + out->opts->margin_len; if (out->end - out->cur <= (long)size) { grow(out, size); } fill_indent(out, indent); fill_value(out, pre, plen); fill_value(out, val, vlen); fill_value(out, suf, slen); *out->cur = '\0'; } static void dump_obj_to_xml(VALUE obj, Options copts, Out out) { VALUE clas = rb_obj_class(obj); out->w_time = (Yes == copts->xsd_date) ? dump_time_xsd : dump_time_thin; out->buf = ALLOC_N(char, 65336); out->end = out->buf + 65325; /* 10 less than end plus extra for possible errors */ out->cur = out->buf; out->circ_cache = 0; out->circ_cnt = 0; out->opts = copts; out->obj = obj; *out->cur = '\0'; if (Yes == copts->circular) { ox_cache8_new(&out->circ_cache); } out->indent = copts->indent; if (ox_document_clas == clas) { dump_gen_doc(obj, -1, out); } else if (ox_element_clas == clas) { dump_gen_element(obj, 0, out); } else { out->w_start = dump_start; out->w_end = dump_end; dump_first_obj(obj, out); } if (0 <= out->indent) { dump_value(out, "\n", 1); } if (Yes == copts->circular) { ox_cache8_delete(out->circ_cache); } } char *ox_write_obj_to_str(VALUE obj, Options copts) { struct _out out; dump_obj_to_xml(obj, copts, &out); return out.buf; } void ox_write_obj_to_file(VALUE obj, const char *path, Options copts) { struct _out out; size_t size; FILE *f; dump_obj_to_xml(obj, copts, &out); size = out.cur - out.buf; if (0 == (f = fopen(path, "w"))) { rb_raise(rb_eIOError, "%s\n", strerror(errno)); } if (size != fwrite(out.buf, 1, size, f)) { int err = ferror(f); rb_raise(rb_eIOError, "Write failed. [%d:%s]\n", err, strerror(err)); } xfree(out.buf); fclose(f); } ox-2.14.17/ext/ox/err.c000066400000000000000000000020421445411231300144720ustar00rootroot00000000000000/* err.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "err.h" #include void ox_err_set(Err e, VALUE clas, const char *format, ...) { va_list ap; va_start(ap, format); e->clas = clas; vsnprintf(e->msg, sizeof(e->msg) - 1, format, ap); va_end(ap); } #if __GNUC__ > 4 _Noreturn void #else void #endif ox_err_raise(Err e) { rb_raise(e->clas, "%s", e->msg); } void _ox_err_set_with_location(Err err, const char *msg, const char *xml, const char *current, const char *file, int line) { int xline = 1; int col = 1; for (; xml < current && '\n' != *current; current--) { col++; } for (; xml < current; current--) { if ('\n' == *current) { xline++; } } ox_err_set(err, ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line); } ox-2.14.17/ext/ox/err.h000066400000000000000000000014571445411231300145100ustar00rootroot00000000000000/* err.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_ERR_H #define OX_ERR_H #include "ruby.h" #define set_error(err, msg, xml, current) _ox_err_set_with_location(err, msg, xml, current, __FILE__, __LINE__) typedef struct _err { VALUE clas; char msg[128]; } *Err; extern VALUE ox_arg_error_class; extern VALUE ox_parse_error_class; extern VALUE ox_syntax_error_class; extern void ox_err_set(Err e, VALUE clas, const char *format, ...); extern void _ox_err_set_with_location(Err err, const char *msg, const char *xml, const char *current, const char *file, int line); extern void ox_err_raise(Err e); inline static void err_init(Err e) { e->clas = Qnil; *e->msg = '\0'; } inline static int err_has(Err e) { return (Qnil != e->clas); } #endif /* OX_ERR_H */ ox-2.14.17/ext/ox/extconf.rb000066400000000000000000000022451445411231300155360ustar00rootroot00000000000000require 'mkmf' extension_name = 'ox' dir_config(extension_name) parts = RUBY_DESCRIPTION.split(' ') type = parts[0].downcase type = 'ree' if 'ruby' == type && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition') platform = RUBY_PLATFORM version = RUBY_VERSION.split('.') puts ">>>>> Creating Makefile for #{type} version #{RUBY_VERSION} on #{platform} <<<<<" dflags = { 'RUBY_TYPE' => type, (type.upcase + '_RUBY') => nil, 'RUBY_VERSION' => RUBY_VERSION, 'RUBY_VERSION_MAJOR' => version[0], 'RUBY_VERSION_MINOR' => version[1], 'RUBY_VERSION_MICRO' => version[2] } dflags.each do |k, v| if v.nil? $CPPFLAGS += " -D#{k}" else $CPPFLAGS += " -D#{k}=#{v}" end end $CPPFLAGS += ' -Wall' # puts "*** $CPPFLAGS: #{$CPPFLAGS}" CONFIG['warnflags'].slice!(/ -Wsuggest-attribute=format/) CONFIG['warnflags'].slice!(/ -Wdeclaration-after-statement/) CONFIG['warnflags'].slice!(/ -Wmissing-noreturn/) have_func('rb_ext_ractor_safe', 'ruby.h') have_func('pthread_mutex_init') have_func('rb_enc_interned_str') have_func('index') have_header('ruby/st.h') have_header('sys/uio.h') have_struct_member('struct tm', 'tm_gmtoff') create_makefile(extension_name) `make clean` ox-2.14.17/ext/ox/gen_load.c000066400000000000000000000260441445411231300154620ustar00rootroot00000000000000/* gen_load.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include "intern.h" #include "ox.h" #include "ruby.h" #include "ruby/encoding.h" static void instruct(PInfo pi, const char *target, Attr attrs, const char *content); static void create_doc(PInfo pi); static void create_prolog_doc(PInfo pi, const char *target, Attr attrs); static void nomode_instruct(PInfo pi, const char *target, Attr attrs, const char *content); static void add_doctype(PInfo pi, const char *docType); static void add_comment(PInfo pi, const char *comment); static void add_cdata(PInfo pi, const char *cdata, size_t len); static void add_text(PInfo pi, char *text, int closed); static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren); static void end_element(PInfo pi, const char *ename); static void add_instruct(PInfo pi, const char *name, Attr attrs, const char *content); extern ParseCallbacks ox_obj_callbacks; struct _parseCallbacks _ox_gen_callbacks = { instruct, /* instruct, */ add_doctype, add_comment, add_cdata, add_text, add_element, end_element, NULL, }; ParseCallbacks ox_gen_callbacks = &_ox_gen_callbacks; struct _parseCallbacks _ox_limited_callbacks = { 0, 0, 0, 0, add_text, add_element, end_element, NULL, }; ParseCallbacks ox_limited_callbacks = &_ox_limited_callbacks; struct _parseCallbacks _ox_nomode_callbacks = { nomode_instruct, add_doctype, add_comment, add_cdata, add_text, add_element, end_element, NULL, }; ParseCallbacks ox_nomode_callbacks = &_ox_nomode_callbacks; static void create_doc(PInfo pi) { VALUE doc; VALUE nodes; helper_stack_init(&pi->helpers); doc = rb_obj_alloc(ox_document_clas); RB_GC_GUARD(doc); nodes = rb_ary_new(); rb_ivar_set(doc, ox_attributes_id, rb_hash_new()); rb_ivar_set(doc, ox_nodes_id, nodes); helper_stack_push(&pi->helpers, 0, nodes, NoCode); pi->obj = doc; } static void create_prolog_doc(PInfo pi, const char *target, Attr attrs) { volatile VALUE doc; volatile VALUE ah; volatile VALUE nodes; volatile VALUE sym; if (!helper_stack_empty(&pi->helpers)) { /* top level object */ ox_err_set(&pi->err, ox_syntax_error_class, "Prolog must be the first element in an XML document.\n"); return; } doc = rb_obj_alloc(ox_document_clas); ah = rb_hash_new(); for (; 0 != attrs->name; attrs++) { if (Qnil != pi->options->attr_key_mod) { sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name)); rb_hash_aset(ah, sym, rb_str_new2(attrs->value)); } else if (Yes == pi->options->sym_keys) { if (0 != pi->options->rb_enc) { VALUE rstr = rb_str_new2(attrs->name); rb_enc_associate(rstr, pi->options->rb_enc); sym = rb_str_intern(rstr); } else { sym = ID2SYM(rb_intern(attrs->name)); } sym = ID2SYM(rb_intern(attrs->name)); rb_hash_aset(ah, sym, rb_str_new2(attrs->value)); } else { volatile VALUE rstr = rb_str_new2(attrs->name); if (0 != pi->options->rb_enc) { rb_enc_associate(rstr, pi->options->rb_enc); } rb_hash_aset(ah, rstr, rb_str_new2(attrs->value)); } if (0 == strcmp("encoding", attrs->name)) { pi->options->rb_enc = rb_enc_find(attrs->value); } } nodes = rb_ary_new(); rb_ivar_set(doc, ox_attributes_id, ah); rb_ivar_set(doc, ox_nodes_id, nodes); helper_stack_push(&pi->helpers, 0, nodes, ArrayCode); pi->obj = doc; } static void instruct(PInfo pi, const char *target, Attr attrs, const char *content) { if (0 == strcmp("xml", target)) { create_prolog_doc(pi, target, attrs); } else if (0 == strcmp("ox", target)) { for (; 0 != attrs->name; attrs++) { if (0 == strcmp("version", attrs->name)) { if (0 != strcmp("1.0", attrs->value)) { ox_err_set(&pi->err, ox_syntax_error_class, "Only Ox XML Object version 1.0 supported, not %s.\n", attrs->value); return; } } /* ignore other instructions */ } } else { add_instruct(pi, target, attrs, content); } } static void nomode_instruct(PInfo pi, const char *target, Attr attrs, const char *content) { if (0 == strcmp("xml", target)) { create_prolog_doc(pi, target, attrs); } else if (0 == strcmp("ox", target)) { for (; 0 != attrs->name; attrs++) { if (0 == strcmp("version", attrs->name)) { if (0 != strcmp("1.0", attrs->value)) { ox_err_set(&pi->err, ox_syntax_error_class, "Only Ox XML Object version 1.0 supported, not %s.\n", attrs->value); return; } } else if (0 == strcmp("mode", attrs->name)) { if (0 == strcmp("object", attrs->value)) { pi->pcb = ox_obj_callbacks; pi->obj = Qnil; helper_stack_init(&pi->helpers); } else if (0 == strcmp("generic", attrs->value)) { pi->pcb = ox_gen_callbacks; } else if (0 == strcmp("limited", attrs->value)) { pi->pcb = ox_limited_callbacks; pi->obj = Qnil; helper_stack_init(&pi->helpers); } else { ox_err_set(&pi->err, ox_syntax_error_class, "%s is not a valid processing instruction mode.\n", attrs->value); return; } } } } else { if (TRACE <= pi->options->trace) { printf("Processing instruction %s ignored.\n", target); } } } static void add_doctype(PInfo pi, const char *docType) { VALUE n = rb_obj_alloc(ox_doctype_clas); VALUE s = rb_str_new2(docType); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } rb_ivar_set(n, ox_at_value_id, s); if (helper_stack_empty(&pi->helpers)) { /* top level object */ create_doc(pi); } rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n); } static void add_comment(PInfo pi, const char *comment) { VALUE n = rb_obj_alloc(ox_comment_clas); VALUE s = rb_str_new2(comment); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } rb_ivar_set(n, ox_at_value_id, s); if (helper_stack_empty(&pi->helpers)) { /* top level object */ create_doc(pi); } rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n); } static void add_cdata(PInfo pi, const char *cdata, size_t len) { VALUE n = rb_obj_alloc(ox_cdata_clas); VALUE s = rb_str_new2(cdata); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } rb_ivar_set(n, ox_at_value_id, s); if (helper_stack_empty(&pi->helpers)) { /* top level object */ create_doc(pi); } rb_ary_push(helper_stack_peek(&pi->helpers)->obj, n); } static void add_text(PInfo pi, char *text, int closed) { VALUE s = rb_str_new2(text); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } if (helper_stack_empty(&pi->helpers)) { /* top level object */ create_doc(pi); } rb_ary_push(helper_stack_peek(&pi->helpers)->obj, s); } static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) { VALUE e; VALUE s = rb_str_new2(ename); if (Qnil != pi->options->element_key_mod) { s = rb_funcall(pi->options->element_key_mod, ox_call_id, 1, s); } if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } e = rb_obj_alloc(ox_element_clas); rb_ivar_set(e, ox_at_value_id, s); if (0 != attrs->name) { volatile VALUE ah = rb_hash_new(); for (; 0 != attrs->name; attrs++) { volatile VALUE sym; if (Qnil != pi->options->attr_key_mod) { sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name)); } else if (Yes == pi->options->sym_keys) { sym = ox_sym_intern(attrs->name, strlen(attrs->name), NULL); } else { sym = ox_str_intern(attrs->name, strlen(attrs->name), NULL); } s = rb_str_new2(attrs->value); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } rb_hash_aset(ah, sym, s); } rb_ivar_set(e, ox_attributes_id, ah); } if (helper_stack_empty(&pi->helpers)) { /* top level object */ pi->obj = e; } else { rb_ary_push(helper_stack_peek(&pi->helpers)->obj, e); } if (hasChildren) { VALUE nodes = rb_ary_new(); rb_ivar_set(e, ox_nodes_id, nodes); helper_stack_push(&pi->helpers, 0, nodes, NoCode); } else { helper_stack_push(&pi->helpers, 0, Qnil, NoCode); // will be popped in end_element } } static void end_element(PInfo pi, const char *ename) { if (!helper_stack_empty(&pi->helpers)) { helper_stack_pop(&pi->helpers); } } static void add_instruct(PInfo pi, const char *name, Attr attrs, const char *content) { VALUE inst; VALUE s = rb_str_new2(name); VALUE c = Qnil; if (0 != content) { c = rb_str_new2(content); } if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); if (0 != content) { rb_enc_associate(c, pi->options->rb_enc); } } inst = rb_obj_alloc(ox_instruct_clas); rb_ivar_set(inst, ox_at_value_id, s); if (0 != content) { rb_ivar_set(inst, ox_at_content_id, c); } else if (0 != attrs->name) { volatile VALUE ah = rb_hash_new(); for (; 0 != attrs->name; attrs++) { volatile VALUE sym; if (Qnil != pi->options->attr_key_mod) { sym = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name)); } else if (Yes == pi->options->sym_keys) { sym = ox_sym_intern(attrs->name, strlen(attrs->name), NULL); } else { sym = ox_str_intern(attrs->name, strlen(attrs->name), NULL); } s = rb_str_new2(attrs->value); if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } rb_hash_aset(ah, sym, s); } rb_ivar_set(inst, ox_attributes_id, ah); } if (helper_stack_empty(&pi->helpers)) { /* top level object */ create_doc(pi); } rb_ary_push(helper_stack_peek(&pi->helpers)->obj, inst); } ox-2.14.17/ext/ox/hash_load.c000066400000000000000000000162651445411231300156400ustar00rootroot00000000000000/* hash_load.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include #include "ox.h" #include "ruby.h" #define MARK_INC 256 // The approach taken for the hash and has_no_attrs parsing is to push just // the key on to the stack and then decide what to do on the way up/out. static VALUE create_top(PInfo pi) { volatile VALUE top = rb_hash_new(); helper_stack_push(&pi->helpers, 0, top, HashCode); pi->obj = top; return top; } static void mark_value(PInfo pi, VALUE val) { if (NULL == pi->marked) { pi->marked = ALLOC_N(VALUE, MARK_INC); pi->mark_size = MARK_INC; } else if (pi->mark_size <= pi->mark_cnt) { pi->mark_size += MARK_INC; REALLOC_N(pi->marked, VALUE, pi->mark_size); } pi->marked[pi->mark_cnt] = val; pi->mark_cnt++; } static bool marked(PInfo pi, VALUE val) { if (NULL != pi->marked) { VALUE *vp = pi->marked + pi->mark_cnt - 1; for (; pi->marked <= vp; vp--) { if (val == *vp) { return true; } } } return false; } static void unmark(PInfo pi, VALUE val) { if (NULL != pi->marked) { VALUE *vp = pi->marked + pi->mark_cnt - 1; int i; for (i = 0; pi->marked <= vp; vp--, i++) { if (val == *vp) { for (; 0 < i; i--, vp++) { *vp = *(vp + 1); } pi->mark_cnt--; break; } } } } static void add_str(PInfo pi, VALUE s) { Helper parent = helper_stack_peek(&pi->helpers); volatile VALUE a; if (0 != pi->options->rb_enc) { rb_enc_associate(s, pi->options->rb_enc); } switch (parent->type) { case NoCode: parent->obj = s; parent->type = StringCode; break; case ArrayCode: rb_ary_push(parent->obj, s); break; default: a = rb_ary_new(); rb_ary_push(a, parent->obj); rb_ary_push(a, s); parent->obj = a; parent->type = ArrayCode; break; } } static void add_text(PInfo pi, char *text, int closed) { add_str(pi, rb_str_new2(text)); } static void add_cdata(PInfo pi, const char *text, size_t len) { add_str(pi, rb_str_new(text, len)); } static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) { if (helper_stack_empty(&pi->helpers)) { create_top(pi); } if (NULL != attrs && NULL != attrs->name) { volatile VALUE h = rb_hash_new(); volatile VALUE key; volatile VALUE val; volatile VALUE a; for (; 0 != attrs->name; attrs++) { if (Qnil != pi->options->attr_key_mod) { key = rb_funcall(pi->options->attr_key_mod, ox_call_id, 1, rb_str_new2(attrs->name)); } else if (Yes == pi->options->sym_keys) { key = rb_id2sym(rb_intern(attrs->name)); } else { key = rb_str_new2(attrs->name); } val = rb_str_new2(attrs->value); if (0 != pi->options->rb_enc) { rb_enc_associate(val, pi->options->rb_enc); } rb_hash_aset(h, key, val); } a = rb_ary_new(); rb_ary_push(a, h); mark_value(pi, a); helper_stack_push(&pi->helpers, rb_intern(ename), a, ArrayCode); } else { helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode); } } static void add_element_no_attrs(PInfo pi, const char *ename, Attr attrs, int hasChildren) { if (helper_stack_empty(&pi->helpers)) { create_top(pi); } helper_stack_push(&pi->helpers, rb_intern(ename), Qnil, NoCode); } static int umark_hash_cb(VALUE key, VALUE value, VALUE x) { unmark((PInfo)x, value); return ST_CONTINUE; } static void end_element_core(PInfo pi, const char *ename, bool check_marked) { Helper e = helper_stack_pop(&pi->helpers); Helper parent = helper_stack_peek(&pi->helpers); volatile VALUE pobj = parent->obj; volatile VALUE found = Qundef; volatile VALUE key; volatile VALUE a; if (NoCode == e->type) { e->obj = Qnil; } if (Qnil != pi->options->element_key_mod) { key = rb_funcall(pi->options->element_key_mod, ox_call_id, 1, rb_id2str(e->var)); } else if (Yes == pi->options->sym_keys) { key = rb_id2sym(e->var); } else { key = rb_id2str(e->var); } // Make sure the parent is a Hash. If not set then make a Hash. If an // Array or non-Hash then append to array or create and append. switch (parent->type) { case NoCode: pobj = rb_hash_new(); parent->obj = pobj; parent->type = HashCode; break; case ArrayCode: pobj = rb_hash_new(); rb_ary_push(parent->obj, pobj); break; case HashCode: found = rb_hash_lookup2(parent->obj, key, Qundef); break; default: a = rb_ary_new(); rb_ary_push(a, parent->obj); pobj = rb_hash_new(); rb_ary_push(a, pobj); parent->obj = a; parent->type = ArrayCode; break; } if (Qundef == found) { rb_hash_aset(pobj, key, e->obj); } else if (RUBY_T_ARRAY == rb_type(found)) { if (check_marked && marked(pi, found)) { unmark(pi, found); a = rb_ary_new(); rb_ary_push(a, found); rb_ary_push(a, e->obj); rb_hash_aset(pobj, key, a); } else { rb_ary_push(found, e->obj); } } else { // something there other than an array if (check_marked && marked(pi, e->obj)) { unmark(pi, e->obj); } a = rb_ary_new(); rb_ary_push(a, found); rb_ary_push(a, e->obj); rb_hash_aset(pobj, key, a); } if (check_marked && NULL != pi->marked && RUBY_T_HASH == rb_type(e->obj)) { rb_hash_foreach(e->obj, umark_hash_cb, (VALUE)pi); } } static void end_element(PInfo pi, const char *ename) { end_element_core(pi, ename, true); } static void end_element_no_attrs(PInfo pi, const char *ename) { end_element_core(pi, ename, false); } static void finish(PInfo pi) { xfree(pi->marked); } struct _parseCallbacks _ox_hash_callbacks = { NULL, NULL, NULL, NULL, add_text, add_element, end_element, finish, }; ParseCallbacks ox_hash_callbacks = &_ox_hash_callbacks; struct _parseCallbacks _ox_hash_cdata_callbacks = { NULL, NULL, NULL, add_cdata, add_text, add_element, end_element, finish, }; ParseCallbacks ox_hash_cdata_callbacks = &_ox_hash_cdata_callbacks; struct _parseCallbacks _ox_hash_no_attrs_callbacks = { NULL, NULL, NULL, NULL, add_text, add_element_no_attrs, end_element_no_attrs, NULL, }; ParseCallbacks ox_hash_no_attrs_callbacks = &_ox_hash_no_attrs_callbacks; struct _parseCallbacks _ox_hash_no_attrs_cdata_callbacks = { NULL, NULL, NULL, add_cdata, add_text, add_element_no_attrs, end_element_no_attrs, NULL, }; ParseCallbacks ox_hash_no_attrs_cdata_callbacks = &_ox_hash_no_attrs_cdata_callbacks; ox-2.14.17/ext/ox/helper.h000066400000000000000000000043711445411231300151750ustar00rootroot00000000000000/* helper.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_HELPER_H #define OX_HELPER_H #include "type.h" #define HELPER_STACK_INC 16 typedef struct _helper { ID var; /* Object var ID */ VALUE obj; /* object created or Qundef if not appropriate */ Type type; /* type of object in obj */ } *Helper; typedef struct _helperStack { struct _helper base[HELPER_STACK_INC]; Helper head; /* current stack */ Helper end; /* stack end */ Helper tail; /* pointer to one past last element name on stack */ } *HelperStack; inline static void helper_stack_init(HelperStack stack) { stack->head = stack->base; stack->end = stack->base + sizeof(stack->base) / sizeof(struct _helper); stack->tail = stack->head; } inline static int helper_stack_empty(HelperStack stack) { return (stack->head == stack->tail); } inline static int helper_stack_depth(HelperStack stack) { return (int)(stack->tail - stack->head); } inline static void helper_stack_cleanup(HelperStack stack) { if (stack->base != stack->head) { xfree(stack->head); stack->head = stack->base; } } inline static Helper helper_stack_push(HelperStack stack, ID var, VALUE obj, Type type) { if (stack->end <= stack->tail) { size_t len = stack->end - stack->head; size_t toff = stack->tail - stack->head; if (stack->base == stack->head) { stack->head = ALLOC_N(struct _helper, len + HELPER_STACK_INC); memcpy(stack->head, stack->base, sizeof(struct _helper) * len); } else { REALLOC_N(stack->head, struct _helper, len + HELPER_STACK_INC); } stack->tail = stack->head + toff; stack->end = stack->head + len + HELPER_STACK_INC; } stack->tail->var = var; stack->tail->obj = obj; stack->tail->type = type; stack->tail++; return stack->tail - 1; } inline static Helper helper_stack_peek(HelperStack stack) { if (stack->head < stack->tail) { return stack->tail - 1; } return 0; } inline static Helper helper_stack_pop(HelperStack stack) { if (stack->head < stack->tail) { stack->tail--; return stack->tail; } return 0; } #endif /* OX_HELPER_H */ ox-2.14.17/ext/ox/intern.c000066400000000000000000000110051445411231300152000ustar00rootroot00000000000000// Copyright (c) 2011, 2021 Peter Ohler. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for license details. #include "intern.h" #include #include "cache.h" #include "ox.h" #include "ruby/version.h" // These are statics but in an attempt to stop the cross linking or maybe // something in Ruby they all have been given an ox prefix. static struct _cache *ox_str_cache = NULL; static VALUE ox_str_cache_obj; static struct _cache *ox_sym_cache = NULL; static VALUE ox_sym_cache_obj; static struct _cache *ox_attr_cache = NULL; static VALUE ox_attr_cache_obj; static struct _cache *ox_id_cache = NULL; static VALUE ox_id_cache_obj; static VALUE form_str(const char *str, size_t len) { return rb_str_freeze(rb_utf8_str_new(str, len)); } static VALUE form_sym(const char *str, size_t len) { return rb_to_symbol(rb_str_freeze(rb_utf8_str_new(str, len))); } static VALUE form_attr(const char *str, size_t len) { char buf[256]; if (sizeof(buf) - 2 <= len) { char *b = ALLOC_N(char, len + 2); ID id; if ('~' == *str) { memcpy(b, str + 1, len - 1); b[len - 1] = '\0'; len -= 2; } else { *b = '@'; memcpy(b + 1, str, len); b[len + 1] = '\0'; } id = rb_intern3(buf, len + 1, rb_utf8_encoding()); xfree(b); return id; } if ('~' == *str) { memcpy(buf, str + 1, len - 1); buf[len - 1] = '\0'; len -= 2; } else { *buf = '@'; memcpy(buf + 1, str, len); buf[len + 1] = '\0'; } return (VALUE)rb_intern3(buf, len + 1, rb_utf8_encoding()); } static VALUE form_id(const char *str, size_t len) { return (VALUE)rb_intern3(str, len, rb_utf8_encoding()); } void ox_hash_init() { VALUE cache_class = rb_define_class_under(Ox, "Cache", rb_cObject); #if RUBY_API_VERSION_CODE >= 30200 rb_undef_alloc_func(cache_class); #endif ox_str_cache = ox_cache_create(0, form_str, true, false); ox_str_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_str_cache); rb_gc_register_address(&ox_str_cache_obj); ox_sym_cache = ox_cache_create(0, form_sym, true, false); ox_sym_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_sym_cache); rb_gc_register_address(&ox_sym_cache_obj); ox_attr_cache = ox_cache_create(0, form_attr, false, false); ox_attr_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_attr_cache); rb_gc_register_address(&ox_attr_cache_obj); ox_id_cache = ox_cache_create(0, form_id, false, false); ox_id_cache_obj = Data_Wrap_Struct(cache_class, ox_cache_mark, ox_cache_free, ox_id_cache); rb_gc_register_address(&ox_id_cache_obj); } VALUE ox_str_intern(const char *key, size_t len, const char **keyp) { // For huge cache sizes over half a million the rb_enc_interned_str // performs slightly better but at more "normal" size of a several // thousands the cache intern performs about 20% better. #if HAVE_RB_ENC_INTERNED_STR && 0 return rb_enc_interned_str(key, len, rb_utf8_encoding()); #else return ox_cache_intern(ox_str_cache, key, len, keyp); #endif } VALUE ox_sym_intern(const char *key, size_t len, const char **keyp) { return ox_cache_intern(ox_sym_cache, key, len, keyp); } ID ox_attr_intern(const char *key, size_t len) { return ox_cache_intern(ox_attr_cache, key, len, NULL); } ID ox_id_intern(const char *key, size_t len) { return ox_cache_intern(ox_id_cache, key, len, NULL); } char *ox_strndup(const char *s, size_t len) { char *d = ALLOC_N(char, len + 1); memcpy(d, s, len); d[len] = '\0'; return d; } VALUE ox_utf8_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) { return ox_str_intern(str, len, strp); } VALUE ox_utf8_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) { return ox_sym_intern(str, len, strp); } VALUE ox_enc_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp) { VALUE sym = rb_str_new2(str); rb_enc_associate(sym, encoding); if (NULL != strp) { *strp = StringValuePtr(sym); } return rb_to_symbol(sym); } VALUE ox_enc_name(const char *str, size_t len, rb_encoding *encoding, const char **strp) { VALUE sym = rb_str_new2(str); rb_enc_associate(sym, encoding); if (NULL != strp) { *strp = StringValuePtr(sym); } return sym; } ox-2.14.17/ext/ox/intern.h000066400000000000000000000020011445411231300152010ustar00rootroot00000000000000// Copyright (c) 2011, 2021 Peter Ohler. All rights reserved. // Licensed under the MIT License. See LICENSE file in the project root for license details. #ifndef OX_INTERN_H #define OX_INTERN_H #include #include struct _parseInfo; extern void ox_hash_init(); extern VALUE ox_str_intern(const char *key, size_t len, const char **keyp); extern VALUE ox_sym_intern(const char *key, size_t len, const char **keyp); extern ID ox_attr_intern(const char *key, size_t len); extern ID ox_id_intern(const char *key, size_t len); extern char *ox_strndup(const char *s, size_t len); extern VALUE ox_utf8_name(const char *str, size_t len, rb_encoding *encoding, const char **strp); extern VALUE ox_utf8_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp); extern VALUE ox_enc_sym(const char *str, size_t len, rb_encoding *encoding, const char **strp); extern VALUE ox_enc_name(const char *str, size_t len, rb_encoding *encoding, const char **strp); #endif /* OX_INTERN_H */ ox-2.14.17/ext/ox/obj_load.c000066400000000000000000000603441445411231300154640ustar00rootroot00000000000000/* obj_load.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include #include "base64.h" #include "intern.h" #include "ox.h" #include "ruby.h" #include "ruby/encoding.h" static void instruct(PInfo pi, const char *target, Attr attrs, const char *content); static void add_text(PInfo pi, char *text, int closed); static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren); static void end_element(PInfo pi, const char *ename); static VALUE parse_time(const char *text, VALUE clas); static VALUE parse_xsd_time(const char *text, VALUE clas); static VALUE parse_double_time(const char *text, VALUE clas); static VALUE parse_regexp(const char *text); static ID get_var_sym_from_attrs(Attr a, void *encoding); static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class); static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class); static VALUE classname2class(const char *name, PInfo pi, VALUE base_class); static unsigned long get_id_from_attrs(PInfo pi, Attr a); static CircArray circ_array_new(void); static void circ_array_free(CircArray ca); static void circ_array_set(CircArray ca, VALUE obj, unsigned long id); static VALUE circ_array_get(CircArray ca, unsigned long id); static void debug_stack(PInfo pi, const char *comment); static void fill_indent(PInfo pi, char *buf, size_t size); struct _parseCallbacks _ox_obj_callbacks = { instruct, // instruct, 0, // add_doctype, 0, // add_comment, 0, // add_cdata, add_text, add_element, end_element, NULL, }; ParseCallbacks ox_obj_callbacks = &_ox_obj_callbacks; extern ParseCallbacks ox_gen_callbacks; inline static VALUE resolve_classname(VALUE mod, const char *class_name, Effort effort, VALUE base_class) { VALUE clas; ID ci = rb_intern(class_name); switch (effort) { case TolerantEffort: if (rb_const_defined_at(mod, ci)) { clas = rb_const_get_at(mod, ci); } else { clas = Qundef; } break; case AutoEffort: if (rb_const_defined_at(mod, ci)) { clas = rb_const_get_at(mod, ci); } else { clas = rb_define_class_under(mod, class_name, base_class); } break; case StrictEffort: default: // raise an error if name is not defined clas = rb_const_get_at(mod, ci); break; } return clas; } inline static VALUE classname2obj(const char *name, PInfo pi, VALUE base_class) { VALUE clas = classname2class(name, pi, base_class); if (Qundef == clas) { return Qnil; } else { return rb_obj_alloc(clas); } } inline static VALUE structname2obj(const char *name) { VALUE ost; const char *s = name; for (; 1; s++) { if ('\0' == *s) { s = name; break; } else if (':' == *s) { s += 2; break; } } ost = rb_const_get(ox_struct_class, rb_intern(s)); return rb_struct_alloc_noinit(ost); } inline static VALUE parse_ulong(const char *s, PInfo pi) { unsigned long n = 0; for (; '\0' != *s; s++) { if ('0' <= *s && *s <= '9') { n = n * 10 + (*s - '0'); } else { set_error(&pi->err, "Invalid number for a julian day", pi->str, pi->s); return Qundef; } } return ULONG2NUM(n); } // 2010-07-09T10:47:45.895826162+09:00 inline static VALUE parse_time(const char *text, VALUE clas) { VALUE t; if (Qnil == (t = parse_double_time(text, clas)) && Qnil == (t = parse_xsd_time(text, clas))) { VALUE args[1]; *args = rb_str_new2(text); t = rb_funcall2(ox_time_class, ox_parse_id, 1, args); } return t; } static VALUE classname2class(const char *name, PInfo pi, VALUE base_class) { VALUE *slot; VALUE clas; if (Qundef == (clas = slot_cache_get(ox_class_cache, name, &slot, 0))) { char class_name[1024]; char *s; const char *n = name; clas = rb_cObject; for (s = class_name; '\0' != *n; n++) { if (':' == *n) { *s = '\0'; n++; if (':' != *n) { set_error(&pi->err, "Invalid classname, expected another ':'", pi->str, pi->s); return Qundef; } if (Qundef == (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) { return Qundef; } s = class_name; } else { *s++ = *n; } } *s = '\0'; if (Qundef != (clas = resolve_classname(clas, class_name, pi->options->effort, base_class))) { *slot = clas; rb_gc_register_address(slot); } } return clas; } static ID get_var_sym_from_attrs(Attr a, void *encoding) { for (; 0 != a->name; a++) { if ('a' == *a->name && '\0' == *(a->name + 1)) { const char *val = a->value; if ('0' <= *val && *val <= '9') { return INT2NUM(atoi(val)); } return ox_id_intern(val, strlen(val)); } } return 0; } static VALUE get_obj_from_attrs(Attr a, PInfo pi, VALUE base_class) { for (; 0 != a->name; a++) { if ('c' == *a->name && '\0' == *(a->name + 1)) { return classname2obj(a->value, pi, base_class); } } return Qundef; } static VALUE get_struct_from_attrs(Attr a) { for (; 0 != a->name; a++) { if ('c' == *a->name && '\0' == *(a->name + 1)) { return structname2obj(a->value); } } return Qundef; } static VALUE get_class_from_attrs(Attr a, PInfo pi, VALUE base_class) { for (; 0 != a->name; a++) { if ('c' == *a->name && '\0' == *(a->name + 1)) { return classname2class(a->value, pi, base_class); } } return Qundef; } static unsigned long get_id_from_attrs(PInfo pi, Attr a) { for (; 0 != a->name; a++) { if ('i' == *a->name && '\0' == *(a->name + 1)) { unsigned long id = 0; const char *text = a->value; char c; for (; '\0' != *text; text++) { c = *text; if ('0' <= c && c <= '9') { id = id * 10 + (c - '0'); } else { set_error(&pi->err, "bad number format", pi->str, pi->s); return 0; } } return id; } } return 0; } static CircArray circ_array_new() { CircArray ca; ca = ALLOC(struct _circArray); ca->objs = ca->obj_array; ca->size = sizeof(ca->obj_array) / sizeof(VALUE); ca->cnt = 0; return ca; } static void circ_array_free(CircArray ca) { if (ca->objs != ca->obj_array) { xfree(ca->objs); } xfree(ca); } static void circ_array_set(CircArray ca, VALUE obj, unsigned long id) { if (0 < id) { unsigned long i; if (ca->size < id) { unsigned long cnt = id + 512; if (ca->objs == ca->obj_array) { ca->objs = ALLOC_N(VALUE, cnt); memcpy(ca->objs, ca->obj_array, sizeof(VALUE) * ca->cnt); } else { REALLOC_N(ca->objs, VALUE, cnt); } ca->size = cnt; } id--; for (i = ca->cnt; i < id; i++) { ca->objs[i] = Qundef; } ca->objs[id] = obj; if (ca->cnt <= id) { ca->cnt = id + 1; } } } static VALUE circ_array_get(CircArray ca, unsigned long id) { VALUE obj = Qundef; if (id <= ca->cnt) { obj = ca->objs[id - 1]; } return obj; } static VALUE parse_regexp(const char *text) { const char *te; int options = 0; te = text + strlen(text) - 1; #ifdef ONIG_OPTION_IGNORECASE for (; text < te && '/' != *te; te--) { switch (*te) { case 'i': options |= ONIG_OPTION_IGNORECASE; break; case 'm': options |= ONIG_OPTION_MULTILINE; break; case 'x': options |= ONIG_OPTION_EXTEND; break; default: break; } } #endif return rb_reg_new(text + 1, te - text - 1, options); } static void instruct(PInfo pi, const char *target, Attr attrs, const char *content) { if (0 == strcmp("xml", target)) { for (; 0 != attrs->name; attrs++) { if (0 == strcmp("encoding", attrs->name)) { pi->options->rb_enc = rb_enc_find(attrs->value); } } } } static void add_text(PInfo pi, char *text, int closed) { Helper h = helper_stack_peek(&pi->helpers); if (!closed) { set_error(&pi->err, "Text not closed", pi->str, pi->s); return; } if (0 == h) { set_error(&pi->err, "Unexpected text", pi->str, pi->s); return; } if (DEBUG <= pi->options->trace) { char indent[128]; fill_indent(pi, indent, sizeof(indent)); printf("%s '%s' to type %c\n", indent, text, h->type); } switch (h->type) { case NoCode: case StringCode: h->obj = rb_str_new2(text); if (0 != pi->options->rb_enc) { rb_enc_associate(h->obj, pi->options->rb_enc); } if (0 != pi->circ_array) { circ_array_set(pi->circ_array, h->obj, (unsigned long)pi->id); } break; case FixnumCode: { long n = 0; char c; int neg = 0; if ('-' == *text) { neg = 1; text++; } for (; '\0' != *text; text++) { c = *text; if ('0' <= c && c <= '9') { n = n * 10 + (c - '0'); } else { set_error(&pi->err, "bad number format", pi->str, pi->s); return; } } if (neg) { n = -n; } h->obj = LONG2NUM(n); break; } case FloatCode: h->obj = rb_float_new(strtod(text, 0)); break; case SymbolCode: h->obj = ox_sym_intern(text, strlen(text), NULL); break; case DateCode: { VALUE args[1]; if (Qundef == (*args = parse_ulong(text, pi))) { return; } h->obj = rb_funcall2(ox_date_class, ox_jd_id, 1, args); break; } case TimeCode: h->obj = parse_time(text, ox_time_class); break; case String64Code: { unsigned long str_size = b64_orig_size(text); VALUE v; char *str = ALLOCA_N(char, str_size + 1); from_base64(text, (uchar *)str); v = rb_str_new(str, str_size); if (0 != pi->options->rb_enc) { rb_enc_associate(v, pi->options->rb_enc); } if (0 != pi->circ_array) { circ_array_set(pi->circ_array, v, (unsigned long)h->obj); } h->obj = v; break; } case Symbol64Code: { unsigned long str_size = b64_orig_size(text); char *str = ALLOCA_N(char, str_size + 1); from_base64(text, (uchar *)str); h->obj = ox_sym_intern(str, strlen(str), NULL); break; } case RegexpCode: if ('/' == *text) { h->obj = parse_regexp(text); } else { unsigned long str_size = b64_orig_size(text); char *str = ALLOCA_N(char, str_size + 1); from_base64(text, (uchar *)str); h->obj = parse_regexp(str); } break; case BignumCode: h->obj = rb_cstr_to_inum(text, 10, 1); break; case BigDecimalCode: h->obj = rb_funcall(rb_cObject, ox_bigdecimal_id, 1, rb_str_new2(text)); break; default: h->obj = Qnil; break; } } static void add_element(PInfo pi, const char *ename, Attr attrs, int hasChildren) { Attr a; Helper h; unsigned long id; if (TRACE <= pi->options->trace) { char buf[1024]; char indent[128]; char *s = buf; char *end = buf + sizeof(buf) - 2; s += snprintf(s, end - s, " <%s%s", (hasChildren) ? "" : "/", ename); for (a = attrs; 0 != a->name; a++) { s += snprintf(s, end - s, " %s=%s", a->name, a->value); } *s++ = '>'; *s++ = '\0'; if (DEBUG <= pi->options->trace) { printf("===== add element stack(%d) =====\n", helper_stack_depth(&pi->helpers)); debug_stack(pi, buf); } else { fill_indent(pi, indent, sizeof(indent)); printf("%s%s\n", indent, buf); } } if (helper_stack_empty(&pi->helpers)) { // top level object if (0 != (id = get_id_from_attrs(pi, attrs))) { pi->circ_array = circ_array_new(); } } if ('\0' != ename[1]) { set_error(&pi->err, "Invalid element name", pi->str, pi->s); return; } h = helper_stack_push(&pi->helpers, get_var_sym_from_attrs(attrs, (void *)pi->options->rb_enc), Qundef, *ename); switch (h->type) { case NilClassCode: h->obj = Qnil; break; case TrueClassCode: h->obj = Qtrue; break; case FalseClassCode: h->obj = Qfalse; break; case StringCode: // h->obj will be replaced by add_text if it is called h->obj = ox_empty_string; if (0 != pi->circ_array) { pi->id = get_id_from_attrs(pi, attrs); circ_array_set(pi->circ_array, h->obj, pi->id); } break; case FixnumCode: case FloatCode: case SymbolCode: case Symbol64Code: case RegexpCode: case BignumCode: case BigDecimalCode: case ComplexCode: case DateCode: case TimeCode: case RationalCode: // sub elements read next // value will be read in the following add_text h->obj = Qundef; break; case String64Code: h->obj = Qundef; if (0 != pi->circ_array) { pi->id = get_id_from_attrs(pi, attrs); } break; case ArrayCode: h->obj = rb_ary_new(); if (0 != pi->circ_array) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } break; case HashCode: h->obj = rb_hash_new(); if (0 != pi->circ_array) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } break; case RangeCode: h->obj = rb_ary_new_from_args(3, Qnil, Qnil, Qfalse); break; case RawCode: if (hasChildren) { h->obj = ox_parse(pi->s, pi->end - pi->s, ox_gen_callbacks, &pi->s, pi->options, &pi->err); if (0 != pi->circ_array) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } } else { h->obj = Qnil; } break; case ExceptionCode: if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, rb_eException))) { return; } if (0 != pi->circ_array && Qnil != h->obj) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } break; case ObjectCode: if (Qundef == (h->obj = get_obj_from_attrs(attrs, pi, ox_bag_clas))) { return; } if (0 != pi->circ_array && Qnil != h->obj) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } break; case StructCode: h->obj = get_struct_from_attrs(attrs); if (0 != pi->circ_array) { circ_array_set(pi->circ_array, h->obj, get_id_from_attrs(pi, attrs)); } break; case ClassCode: if (Qundef == (h->obj = get_class_from_attrs(attrs, pi, ox_bag_clas))) { return; } break; case RefCode: h->obj = Qundef; if (0 != pi->circ_array) { h->obj = circ_array_get(pi->circ_array, get_id_from_attrs(pi, attrs)); } if (Qundef == h->obj) { set_error(&pi->err, "Invalid circular reference", pi->str, pi->s); return; } break; default: set_error(&pi->err, "Invalid element name", pi->str, pi->s); return; break; } if (DEBUG <= pi->options->trace) { debug_stack(pi, " -----------"); } } static void end_element(PInfo pi, const char *ename) { if (TRACE <= pi->options->trace) { char indent[128]; if (DEBUG <= pi->options->trace) { char buf[1024]; printf("===== end element stack(%d) =====\n", helper_stack_depth(&pi->helpers)); snprintf(buf, sizeof(buf) - 1, "", ename); debug_stack(pi, buf); } else { fill_indent(pi, indent, sizeof(indent)); printf("%s\n", indent, ename); } } if (!helper_stack_empty(&pi->helpers)) { Helper h = helper_stack_pop(&pi->helpers); Helper ph = helper_stack_peek(&pi->helpers); if (ox_empty_string == h->obj) { // special catch for empty strings h->obj = rb_str_new2(""); } else if (Qundef == h->obj) { set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s); return; } else if (RangeCode == h->type) { // Expect an array of 3 elements. const VALUE *ap = RARRAY_PTR(h->obj); h->obj = rb_range_new(*ap, *(ap + 1), Qtrue == *(ap + 2)); } pi->obj = h->obj; if (0 != ph) { switch (ph->type) { case ArrayCode: rb_ary_push(ph->obj, h->obj); break; case ExceptionCode: case ObjectCode: if (Qnil != ph->obj) { if (0 == h->var || NULL == rb_id2name(h->var)) { set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s); return; } if (RUBY_T_OBJECT != rb_type(ph->obj)) { set_error(&pi->err, "Corrupt object encoding", pi->str, pi->s); return; } rb_ivar_set(ph->obj, h->var, h->obj); } break; case StructCode: if (0 == h->var) { set_error(&pi->err, "Invalid element for object mode", pi->str, pi->s); return; } rb_struct_aset(ph->obj, h->var, h->obj); break; case HashCode: // put back h helper_stack_push(&pi->helpers, h->var, h->obj, KeyCode); break; case RangeCode: if (ox_beg_id == h->var) { rb_ary_store(ph->obj, 0, h->obj); } else if (ox_end_id == h->var) { rb_ary_store(ph->obj, 1, h->obj); } else if (ox_excl_id == h->var) { rb_ary_store(ph->obj, 2, h->obj); } else { set_error(&pi->err, "Invalid range attribute", pi->str, pi->s); return; } break; case KeyCode: { Helper gh; helper_stack_pop(&pi->helpers); if (NULL == (gh = helper_stack_peek(&pi->helpers)) || Qundef == ph->obj || Qundef == h->obj) { set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s); return; } rb_hash_aset(gh->obj, ph->obj, h->obj); } break; case ComplexCode: if (Qundef == ph->obj) { ph->obj = h->obj; } else { ph->obj = rb_complex_new(ph->obj, h->obj); } break; case RationalCode: { if (Qundef == h->obj || RUBY_T_FIXNUM != rb_type(h->obj)) { set_error(&pi->err, "Invalid object format", pi->str, pi->s); return; } if (Qundef == ph->obj) { ph->obj = h->obj; } else { if (Qundef == ph->obj || RUBY_T_FIXNUM != rb_type(ph->obj)) { set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s); return; } #ifdef RUBINIUS_RUBY ph->obj = rb_Rational(ph->obj, h->obj); #else ph->obj = rb_rational_new(ph->obj, h->obj); #endif } break; } default: set_error(&pi->err, "Corrupt parse stack, container is wrong type", pi->str, pi->s); return; break; } } } if (0 != pi->circ_array && helper_stack_empty(&pi->helpers)) { circ_array_free(pi->circ_array); pi->circ_array = 0; } if (DEBUG <= pi->options->trace) { debug_stack(pi, " ----------"); } } static VALUE parse_double_time(const char *text, VALUE clas) { long v = 0; long v2 = 0; const char *dot = 0; char c; for (; '.' != *text; text++) { c = *text; if (c < '0' || '9' < c) { return Qnil; } v = 10 * v + (long)(c - '0'); } dot = text++; for (; '\0' != *text && text - dot <= 6; text++) { c = *text; if (c < '0' || '9' < c) { return Qnil; } v2 = 10 * v2 + (long)(c - '0'); } for (; text - dot <= 9; text++) { v2 *= 10; } return rb_time_nano_new(v, v2); } typedef struct _tp { int cnt; char end; char alt; } *Tp; static VALUE parse_xsd_time(const char *text, VALUE clas) { long cargs[10]; long *cp = cargs; long v; int i; char c; struct _tp tpa[10] = {{4, '-', '-'}, {2, '-', '-'}, {2, 'T', 'T'}, {2, ':', ':'}, {2, ':', ':'}, {2, '.', '.'}, {9, '+', '-'}, {2, ':', ':'}, {2, '\0', '\0'}, {0, '\0', '\0'}}; Tp tp = tpa; struct tm tm; for (; 0 != tp->cnt; tp++) { for (i = tp->cnt, v = 0; 0 < i; text++, i--) { c = *text; if (c < '0' || '9' < c) { if (tp->end == c || tp->alt == c) { break; } return Qnil; } v = 10 * v + (long)(c - '0'); } c = *text++; if (tp->end != c && tp->alt != c) { return Qnil; } *cp++ = v; } tm.tm_year = (int)cargs[0] - 1900; tm.tm_mon = (int)cargs[1] - 1; tm.tm_mday = (int)cargs[2]; tm.tm_hour = (int)cargs[3]; tm.tm_min = (int)cargs[4]; tm.tm_sec = (int)cargs[5]; return rb_time_nano_new(mktime(&tm), cargs[6]); } // debug functions static void fill_indent(PInfo pi, char *buf, size_t size) { size_t cnt; if (0 < (cnt = helper_stack_depth(&pi->helpers))) { cnt *= 2; if (size < cnt + 1) { cnt = size - 1; } memset(buf, ' ', cnt); buf += cnt; } *buf = '\0'; } static void debug_stack(PInfo pi, const char *comment) { char indent[128]; Helper h; fill_indent(pi, indent, sizeof(indent)); printf("%s%s\n", indent, comment); if (!helper_stack_empty(&pi->helpers)) { for (h = pi->helpers.head; h < pi->helpers.tail; h++) { const char *clas = "---"; const char *key = "---"; if (Qundef != h->obj) { VALUE c = rb_obj_class(h->obj); clas = rb_class2name(c); } if (0 != h->var) { if (HashCode == h->type) { VALUE v; v = rb_String(h->var); key = StringValuePtr(v); } else if (ObjectCode == (h - 1)->type || ExceptionCode == (h - 1)->type || RangeCode == (h - 1)->type || StructCode == (h - 1)->type) { key = rb_id2name(h->var); } else { printf("%s*** corrupt stack ***\n", indent); } } printf("%s [%c] %s : %s\n", indent, h->type, clas, key); } } } ox-2.14.17/ext/ox/ox.c000066400000000000000000001774211445411231300143460ustar00rootroot00000000000000/* ox.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "ox.h" #include #include #include #include #include #include #include "intern.h" #include "ruby.h" #include "sax.h" /* maximum to allocate on the stack, arbitrary limit */ #define SMALL_XML 4096 #define WITH_CACHE_TESTS 0 typedef struct _yesNoOpt { VALUE sym; char *attr; } *YesNoOpt; void Init_ox(); VALUE Ox = Qnil; ID ox_abort_id; ID ox_at_column_id; ID ox_at_content_id; ID ox_at_id; ID ox_at_line_id; ID ox_at_pos_id; ID ox_at_value_id; ID ox_attr_id; ID ox_attr_value_id; ID ox_attributes_id; ID ox_attrs_done_id; ID ox_beg_id; ID ox_bigdecimal_id; ID ox_call_id; ID ox_cdata_id; ID ox_comment_id; ID ox_den_id; ID ox_doctype_id; ID ox_end_element_id; ID ox_end_id; ID ox_end_instruct_id; ID ox_error_id; ID ox_excl_id; ID ox_external_encoding_id; ID ox_fileno_id; ID ox_force_encoding_id; ID ox_inspect_id; ID ox_instruct_id; ID ox_jd_id; ID ox_keys_id; ID ox_local_id; ID ox_mesg_id; ID ox_message_id; ID ox_new_id; ID ox_nodes_id; ID ox_num_id; ID ox_parse_id; ID ox_pos_id; ID ox_read_id; ID ox_readpartial_id; ID ox_start_element_id; ID ox_string_id; ID ox_text_id; ID ox_to_c_id; ID ox_value_id; VALUE ox_encoding_sym; VALUE ox_version_sym; VALUE ox_standalone_sym; VALUE ox_indent_sym; VALUE ox_size_sym; VALUE ox_empty_string; VALUE ox_zero_fixnum; VALUE ox_sym_bank; // Array VALUE ox_arg_error_class; VALUE ox_bag_clas; VALUE ox_bigdecimal_class; VALUE ox_cdata_clas; VALUE ox_comment_clas; VALUE ox_raw_clas; VALUE ox_date_class; VALUE ox_doctype_clas; VALUE ox_document_clas; VALUE ox_element_clas; VALUE ox_instruct_clas; VALUE ox_parse_error_class; VALUE ox_stringio_class; VALUE ox_struct_class; VALUE ox_syntax_error_class; VALUE ox_time_class; SlotCache ox_class_cache = 0; static VALUE abort_sym; static VALUE active_sym; static VALUE attr_key_mod_sym; static VALUE auto_define_sym; static VALUE auto_sym; static VALUE block_sym; static VALUE circular_sym; static VALUE convert_special_sym; static VALUE effort_sym; static VALUE generic_sym; static VALUE hash_no_attrs_sym; static VALUE hash_sym; static VALUE inactive_sym; static VALUE invalid_replace_sym; static VALUE limited_sym; static VALUE margin_sym; static VALUE mode_sym; static VALUE nest_ok_sym; static VALUE no_empty_sym; static VALUE object_sym; static VALUE off_sym; static VALUE opt_format_sym; static VALUE optimized_sym; static VALUE overlay_sym; static VALUE skip_none_sym; static VALUE skip_off_sym; static VALUE skip_return_sym; static VALUE skip_sym; static VALUE skip_white_sym; static VALUE smart_sym; static VALUE strict_sym; static VALUE strip_namespace_sym; static VALUE symbolize_keys_sym; static VALUE symbolize_sym; static VALUE tolerant_sym; static VALUE trace_sym; static VALUE with_cdata_sym; static VALUE with_dtd_sym; static VALUE with_instruct_sym; static VALUE with_xml_sym; static VALUE xsd_date_sym; static VALUE element_key_mod_sym; static ID encoding_id; static ID has_key_id; rb_encoding *ox_utf8_encoding = 0; struct _options ox_default_options = { {'\0'}, // encoding {'\0'}, // margin 2, // indent 0, // trace 0, // margin_len No, // with_dtd No, // with_xml No, // with_instruct No, // circular No, // xsd_date NoMode, // mode StrictEffort, // effort Yes, // sym_keys SpcSkip, // skip No, // smart true, // convert_special No, // allow_invalid false, // no_empty false, // with_cdata {'\0'}, // inv_repl {'\0'}, // strip_ns NULL, // html_hints Qnil, // attr_key_mod; Qnil, // element_key_mod; 0 // rb_enc }; extern ParseCallbacks ox_obj_callbacks; extern ParseCallbacks ox_gen_callbacks; extern ParseCallbacks ox_limited_callbacks; extern ParseCallbacks ox_nomode_callbacks; extern ParseCallbacks ox_hash_callbacks; extern ParseCallbacks ox_hash_cdata_callbacks; extern ParseCallbacks ox_hash_no_attrs_callbacks; extern ParseCallbacks ox_hash_no_attrs_cdata_callbacks; static void parse_dump_options(VALUE ropts, Options copts); static char *defuse_bom(char *xml, Options options) { switch ((uint8_t)*xml) { case 0xEF: // UTF-8 if (0xBB == (uint8_t)xml[1] && 0xBF == (uint8_t)xml[2]) { options->rb_enc = ox_utf8_encoding; xml += 3; } else { rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n"); } break; #if 0 case 0xFE: // UTF-16BE if (0xFF == (uint8_t)xml[1]) { options->rb_enc = ox_utf16be_encoding; xml += 2; } else { rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n"); } break; case 0xFF: // UTF-16LE or UTF-32LE if (0xFE == (uint8_t)xml[1]) { if (0x00 == (uint8_t)xml[2] && 0x00 == (uint8_t)xml[3]) { options->rb_enc = ox_utf32le_encoding; xml += 4; } else { options->rb_enc = ox_utf16le_encoding; xml += 2; } } else { rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n"); } break; case 0x00: // UTF-32BE if (0x00 == (uint8_t)xml[1] && 0xFE == (uint8_t)xml[2] && 0xFF == (uint8_t)xml[3]) { options->rb_enc = ox_utf32be_encoding; xml += 4; } else { rb_raise(ox_parse_error_class, "Invalid BOM in XML string.\n"); } break; #endif default: // Let it fail if there is a BOM that is not UTF-8. Other BOM options // are not ASCII compatible. break; } return xml; } static VALUE hints_to_overlay(Hints hints) { volatile VALUE overlay = rb_hash_new(); Hint h; int i; VALUE ov; for (i = hints->size, h = hints->hints; 0 < i; i--, h++) { switch (h->overlay) { case InactiveOverlay: ov = inactive_sym; break; case BlockOverlay: ov = block_sym; break; case OffOverlay: ov = off_sym; break; case AbortOverlay: ov = abort_sym; break; case NestOverlay: ov = nest_ok_sym; break; case ActiveOverlay: default: ov = active_sym; break; } rb_hash_aset(overlay, rb_str_new2(h->name), ov); } return overlay; } /* call-seq: default_options() => Hash * * Returns the default load and dump options as a Hash. The options are * - _:margin_ [String] left margin to inset when dumping * - _:indent_ [Fixnum] number of spaces to indent each element in an XML document * - _:trace_ [Fixnum] trace level where 0 is silent * - _:encoding_ [String] character encoding for the XML file * - _:with_dtd_ [true|false|nil] include DTD in the dump * - _:with_instruct_ [true|false|nil] include instructions in the dump * - _:with_xml_ [true|false|nil] include XML prolog in the dump * - _:circular_ [true|false|nil] support circular references while dumping * - _:xsd_date_ [true|false|nil] use XSD date format instead of decimal format * - _:mode_ [:object|:generic|:limited|:hash|:hash_no_attrs|nil] load method to use for XML * - _:effort_ [:strict|:tolerant|:auto_define] set the tolerance level for loading * - _:symbolize_keys_ [true|false|nil] symbolize element attribute keys or leave as Strings * - _:element_key_mod_ [Proc|nil] converts element keys on parse if not nil * - _:attr_key_mod_ [Proc|nil] converts attribute keys on parse if not nil * - _:skip_ [:skip_none|:skip_return|:skip_white|:skip_off] determines how to handle white space in text * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html) * - _:convert_special_ [true|false|nil] flag indicating special characters like < are converted with the SAX parser * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include anyway * as hex. A string, limited to 10 characters will replace the invalid character with the replace. * - _:no_empty_ [true|false|nil] flag indicating there should be no empty elements in a dump * - _:with_cdata_ [true|false] includes cdata in hash_load results * - _:strip_namespace_ [String|true|false] false or "" results in no namespace stripping. A string of "*" or true will * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped. * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of * - _:active_ - make the normal callback for the element * - _:nest_ok_ - active but the nesting check is ignored * - _:inactive_ - do not make the element start, end, or attribute callbacks for this element only * - _:block_ - block this and all children callbacks * - _:off_ - block this element and it's children unless the child element is active * - _:abort_ - abort the html processing and return * * *return* [Hash] all current option settings. * * Note that an indent of less than zero will result in a tight one line output * unless the text in the XML fields contain new line characters. */ static VALUE get_def_opts(VALUE self) { VALUE opts = rb_hash_new(); int elen = (int)strlen(ox_default_options.encoding); rb_hash_aset(opts, ox_encoding_sym, (0 == elen) ? Qnil : rb_str_new(ox_default_options.encoding, elen)); rb_hash_aset(opts, margin_sym, rb_str_new(ox_default_options.margin, ox_default_options.margin_len)); rb_hash_aset(opts, ox_indent_sym, INT2FIX(ox_default_options.indent)); rb_hash_aset(opts, trace_sym, INT2FIX(ox_default_options.trace)); rb_hash_aset(opts, with_dtd_sym, (Yes == ox_default_options.with_dtd) ? Qtrue : ((No == ox_default_options.with_dtd) ? Qfalse : Qnil)); rb_hash_aset(opts, with_xml_sym, (Yes == ox_default_options.with_xml) ? Qtrue : ((No == ox_default_options.with_xml) ? Qfalse : Qnil)); rb_hash_aset( opts, with_instruct_sym, (Yes == ox_default_options.with_instruct) ? Qtrue : ((No == ox_default_options.with_instruct) ? Qfalse : Qnil)); rb_hash_aset(opts, circular_sym, (Yes == ox_default_options.circular) ? Qtrue : ((No == ox_default_options.circular) ? Qfalse : Qnil)); rb_hash_aset(opts, xsd_date_sym, (Yes == ox_default_options.xsd_date) ? Qtrue : ((No == ox_default_options.xsd_date) ? Qfalse : Qnil)); rb_hash_aset(opts, symbolize_keys_sym, (Yes == ox_default_options.sym_keys) ? Qtrue : ((No == ox_default_options.sym_keys) ? Qfalse : Qnil)); rb_hash_aset(opts, attr_key_mod_sym, ox_default_options.attr_key_mod); rb_hash_aset(opts, element_key_mod_sym, ox_default_options.element_key_mod); rb_hash_aset(opts, smart_sym, (Yes == ox_default_options.smart) ? Qtrue : ((No == ox_default_options.smart) ? Qfalse : Qnil)); rb_hash_aset(opts, convert_special_sym, (ox_default_options.convert_special) ? Qtrue : Qfalse); rb_hash_aset(opts, no_empty_sym, (ox_default_options.no_empty) ? Qtrue : Qfalse); rb_hash_aset(opts, with_cdata_sym, (ox_default_options.with_cdata) ? Qtrue : Qfalse); switch (ox_default_options.mode) { case ObjMode: rb_hash_aset(opts, mode_sym, object_sym); break; case GenMode: rb_hash_aset(opts, mode_sym, generic_sym); break; case LimMode: rb_hash_aset(opts, mode_sym, limited_sym); break; case HashMode: rb_hash_aset(opts, mode_sym, hash_sym); break; case HashNoAttrMode: rb_hash_aset(opts, mode_sym, hash_no_attrs_sym); break; case NoMode: default: rb_hash_aset(opts, mode_sym, Qnil); break; } switch (ox_default_options.effort) { case StrictEffort: rb_hash_aset(opts, effort_sym, strict_sym); break; case TolerantEffort: rb_hash_aset(opts, effort_sym, tolerant_sym); break; case AutoEffort: rb_hash_aset(opts, effort_sym, auto_define_sym); break; case NoEffort: default: rb_hash_aset(opts, effort_sym, Qnil); break; } switch (ox_default_options.skip) { case OffSkip: rb_hash_aset(opts, skip_sym, skip_off_sym); break; case NoSkip: rb_hash_aset(opts, skip_sym, skip_none_sym); break; case CrSkip: rb_hash_aset(opts, skip_sym, skip_return_sym); break; case SpcSkip: rb_hash_aset(opts, skip_sym, skip_white_sym); break; default: rb_hash_aset(opts, skip_sym, Qnil); break; } if (Yes == ox_default_options.allow_invalid) { rb_hash_aset(opts, invalid_replace_sym, Qnil); } else { rb_hash_aset(opts, invalid_replace_sym, rb_str_new(ox_default_options.inv_repl + 1, (int)*ox_default_options.inv_repl)); } if ('\0' == *ox_default_options.strip_ns) { rb_hash_aset(opts, strip_namespace_sym, Qfalse); } else if ('*' == *ox_default_options.strip_ns && '\0' == ox_default_options.strip_ns[1]) { rb_hash_aset(opts, strip_namespace_sym, Qtrue); } else { rb_hash_aset(opts, strip_namespace_sym, rb_str_new(ox_default_options.strip_ns, strlen(ox_default_options.strip_ns))); } if (NULL == ox_default_options.html_hints) { // rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_hints_html())); rb_hash_aset(opts, overlay_sym, Qnil); } else { rb_hash_aset(opts, overlay_sym, hints_to_overlay(ox_default_options.html_hints)); } return opts; } static int set_overlay(VALUE key, VALUE value, VALUE ctx) { Hints hints = (Hints)ctx; Hint hint; if (NULL != (hint = ox_hint_find(hints, StringValuePtr(key)))) { if (active_sym == value) { hint->overlay = ActiveOverlay; } else if (inactive_sym == value) { hint->overlay = InactiveOverlay; } else if (block_sym == value) { hint->overlay = BlockOverlay; } else if (nest_ok_sym == value) { hint->overlay = NestOverlay; } else if (off_sym == value) { hint->overlay = OffOverlay; } else if (abort_sym == value) { hint->overlay = AbortOverlay; } } return ST_CONTINUE; } /* call-seq: sax_html_overlay() => Hash * * Returns an overlay hash that can be modified and used as an overlay in the * default options or in the sax_html() function call. Values for the keys are: * - _:active_ - make the normal callback for the element * - _:nest_ok_ - active but ignore nest check * - _:inactive_ - do not make the element start, end, or attribute callbacks for this element only * - _:block_ - block this and all children callbacks * - _:off_ - block this element and it's children unless the child element is active * - _:abort_ - abort the html processing and return * * *return* [Hash] default SAX HTML settings */ static VALUE sax_html_overlay(VALUE self) { return hints_to_overlay(ox_hints_html()); } /* call-seq: default_options=(opts) * * Sets the default options for load and dump. * - +opts+ [Hash] opts options to change * - _:margin_ [String] left margin to inset when dumping * - _:indent_ [Fixnum] number of spaces to indent each element in an XML document * - _:trace_ [Fixnum] trace level where 0 is silent * - _:encoding_ [String] character encoding for the XML file * - _:with_dtd_ [true|false|nil] include DTD in the dump * - _:with_instruct_ [true|false|nil] include instructions in the dump * - _:with_xml_ [true|false|nil] include XML prolog in the dump * - _:circular_ [true|false|nil] support circular references while dumping * - _:xsd_date_ [true|false|nil] use XSD date format instead of decimal format * - _:mode_ [:object|:generic|:limited|:hash|:hash_no_attrs|nil] load method to use for XML * - _:effort_ [:strict|:tolerant|:auto_define] set the tolerance level for loading * - _:symbolize_keys_ [true|false|nil] symbolize element attribute keys or leave as Strings * - _:element_key_mod_ [Proc|nil] converts element keys on parse if not nil * - _:attr_key_mod_ [Proc|nil] converts attribute keys on parse if not nil * - _:skip_ [:skip_none|:skip_return|:skip_white|:skip_off] determines how to handle white space in text * - _:smart_ [true|false|nil] flag indicating the SAX parser uses hints if available (use with html) * - _:invalid_replace_ [nil|String] replacement string for invalid XML characters on dump. nil indicates include * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace. * - _:strip_namespace_ [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true * will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped. * - _:with_cdata_ [true|false] includes cdata in hash_load results * - _:overlay_ [Hash] a Hash of keys that match html element names and values that are one of * - _:active_ - make the normal callback for the element * - _:nest_ok_ - active but ignore nest check * - _:inactive_ - do not make the element start, end, or attribute callbacks for this element only * - _:block_ - block this and all children callbacks * - _:off_ - block this element and it's children unless the child element is active * - _:abort_ - abort the html processing and return * * *return* [nil] */ static VALUE set_def_opts(VALUE self, VALUE opts) { struct _yesNoOpt ynos[] = {{with_xml_sym, &ox_default_options.with_xml}, {with_dtd_sym, &ox_default_options.with_dtd}, {with_instruct_sym, &ox_default_options.with_instruct}, {xsd_date_sym, &ox_default_options.xsd_date}, {circular_sym, &ox_default_options.circular}, {symbolize_keys_sym, &ox_default_options.sym_keys}, {smart_sym, &ox_default_options.smart}, {Qnil, 0}}; YesNoOpt o; VALUE v; Check_Type(opts, T_HASH); v = rb_hash_aref(opts, ox_encoding_sym); if (Qnil == v) { *ox_default_options.encoding = '\0'; } else { Check_Type(v, T_STRING); strncpy(ox_default_options.encoding, StringValuePtr(v), sizeof(ox_default_options.encoding) - 1); ox_default_options.rb_enc = rb_enc_find(ox_default_options.encoding); } v = rb_hash_aref(opts, ox_indent_sym); if (Qnil != v) { Check_Type(v, T_FIXNUM); ox_default_options.indent = FIX2INT(v); } v = rb_hash_aref(opts, trace_sym); if (Qnil != v) { Check_Type(v, T_FIXNUM); ox_default_options.trace = FIX2INT(v); } v = rb_hash_aref(opts, mode_sym); if (Qnil == v) { ox_default_options.mode = NoMode; } else if (object_sym == v) { ox_default_options.mode = ObjMode; } else if (generic_sym == v) { ox_default_options.mode = GenMode; } else if (limited_sym == v) { ox_default_options.mode = LimMode; } else if (hash_sym == v) { ox_default_options.mode = HashMode; } else if (hash_no_attrs_sym == v) { ox_default_options.mode = HashNoAttrMode; } else { rb_raise(ox_parse_error_class, ":mode must be :object, :generic, :limited, :hash, :hash_no_attrs, or nil.\n"); } v = rb_hash_aref(opts, effort_sym); if (Qnil == v) { ox_default_options.effort = NoEffort; } else if (strict_sym == v) { ox_default_options.effort = StrictEffort; } else if (tolerant_sym == v) { ox_default_options.effort = TolerantEffort; } else if (auto_define_sym == v) { ox_default_options.effort = AutoEffort; } else { rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, :auto_define, or nil.\n"); } v = rb_hash_aref(opts, skip_sym); if (Qnil == v) { ox_default_options.skip = NoSkip; } else if (skip_off_sym == v) { ox_default_options.skip = OffSkip; } else if (skip_none_sym == v) { ox_default_options.skip = NoSkip; } else if (skip_return_sym == v) { ox_default_options.skip = CrSkip; } else if (skip_white_sym == v) { ox_default_options.skip = SpcSkip; } else { rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, :skip_off, or nil.\n"); } v = rb_hash_lookup(opts, convert_special_sym); if (Qnil == v) { // no change } else if (Qtrue == v) { ox_default_options.convert_special = 1; } else if (Qfalse == v) { ox_default_options.convert_special = 0; } else { rb_raise(ox_parse_error_class, ":convert_special must be true or false.\n"); } v = rb_hash_lookup(opts, no_empty_sym); if (Qnil == v) { // no change } else if (Qtrue == v) { ox_default_options.no_empty = 1; } else if (Qfalse == v) { ox_default_options.no_empty = 0; } else { rb_raise(ox_parse_error_class, ":no_empty must be true or false.\n"); } v = rb_hash_aref(opts, invalid_replace_sym); if (Qnil == v) { ox_default_options.allow_invalid = Yes; } else { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(ox_default_options.inv_repl) - 2 < (size_t)slen) { rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.", (int)sizeof(ox_default_options.inv_repl) - 2); } strncpy(ox_default_options.inv_repl + 1, StringValuePtr(v), sizeof(ox_default_options.inv_repl) - 1); ox_default_options.inv_repl[sizeof(ox_default_options.inv_repl) - 1] = '\0'; *ox_default_options.inv_repl = (char)slen; ox_default_options.allow_invalid = No; } v = rb_hash_aref(opts, strip_namespace_sym); if (Qfalse == v) { *ox_default_options.strip_ns = '\0'; } else if (Qtrue == v) { *ox_default_options.strip_ns = '*'; ox_default_options.strip_ns[1] = '\0'; } else if (Qnil != v) { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(ox_default_options.strip_ns) - 1 < (size_t)slen) { rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.", (int)sizeof(ox_default_options.strip_ns) - 1); } strncpy(ox_default_options.strip_ns, StringValuePtr(v), sizeof(ox_default_options.strip_ns) - 1); ox_default_options.strip_ns[sizeof(ox_default_options.strip_ns) - 1] = '\0'; } v = rb_hash_aref(opts, margin_sym); if (Qnil != v) { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(ox_default_options.margin) - 1 < (size_t)slen) { rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.", (int)sizeof(ox_default_options.margin) - 1); } strncpy(ox_default_options.margin, StringValuePtr(v), sizeof(ox_default_options.margin) - 1); ox_default_options.margin[sizeof(ox_default_options.margin) - 1] = '\0'; ox_default_options.margin_len = strlen(ox_default_options.margin); } for (o = ynos; 0 != o->attr; o++) { v = rb_hash_lookup(opts, o->sym); if (Qnil == v) { *o->attr = NotSet; } else if (Qtrue == v) { *o->attr = Yes; } else if (Qfalse == v) { *o->attr = No; } else { rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym))); } } v = rb_hash_aref(opts, overlay_sym); if (Qnil == v) { ox_hints_destroy(ox_default_options.html_hints); ox_default_options.html_hints = NULL; } else { int cnt; Check_Type(v, T_HASH); cnt = (int)RHASH_SIZE(v); if (0 == cnt) { ox_hints_destroy(ox_default_options.html_hints); ox_default_options.html_hints = NULL; } else { ox_hints_destroy(ox_default_options.html_hints); ox_default_options.html_hints = ox_hints_dup(ox_hints_html()); rb_hash_foreach(v, set_overlay, (VALUE)ox_default_options.html_hints); } } if (Qnil != (v = rb_hash_lookup(opts, with_cdata_sym))) { ox_default_options.with_cdata = (Qtrue == v); } ox_default_options.element_key_mod = rb_hash_lookup2(opts, element_key_mod_sym, ox_default_options.element_key_mod); ox_default_options.attr_key_mod = rb_hash_lookup2(opts, attr_key_mod_sym, ox_default_options.attr_key_mod); return Qnil; } /* call-seq: parse_obj(xml) => Object * * Parses an XML document String that is in the object format and returns an * Object of the type represented by the XML. This function expects an * optimized XML formated String. For other formats use the more generic * Ox.load() method. Raises an exception if the XML is malformed or the * classes specified in the file are not valid. * - +xml+ [String] XML String in optimized Object format. * *return* [Object] deserialized Object. */ static VALUE to_obj(VALUE self, VALUE ruby_xml) { char *xml, *x; size_t len; VALUE obj; struct _options options = ox_default_options; struct _err err; err_init(&err); Check_Type(ruby_xml, T_STRING); /* the xml string gets modified so make a copy of it */ len = RSTRING_LEN(ruby_xml) + 1; x = defuse_bom(StringValuePtr(ruby_xml), &options); if (SMALL_XML < len) { xml = ALLOC_N(char, len); } else { xml = ALLOCA_N(char, len); } memcpy(xml, x, len); rb_gc_disable(); obj = ox_parse(xml, len - 1, ox_obj_callbacks, 0, &options, &err); if (SMALL_XML < len) { xfree(xml); } RB_GC_GUARD(obj); rb_gc_enable(); if (err_has(&err)) { ox_err_raise(&err); } return obj; } /* call-seq: parse(xml) => Ox::Document or Ox::Element * * Parses and XML document String into an Ox::Document or Ox::Element. * - +xml+ [String] xml XML String * *return* [Ox::Document or Ox::Element] parsed XML document. * * _raise_ [Exception] if the XML is malformed. */ static VALUE to_gen(VALUE self, VALUE ruby_xml) { char *xml, *x; size_t len; VALUE obj; struct _options options = ox_default_options; struct _err err; err_init(&err); Check_Type(ruby_xml, T_STRING); /* the xml string gets modified so make a copy of it */ len = RSTRING_LEN(ruby_xml) + 1; x = defuse_bom(StringValuePtr(ruby_xml), &options); if (SMALL_XML < len) { xml = ALLOC_N(char, len); } else { xml = ALLOCA_N(char, len); } memcpy(xml, x, len); obj = ox_parse(xml, len - 1, ox_gen_callbacks, 0, &options, &err); if (SMALL_XML < len) { xfree(xml); } if (err_has(&err)) { ox_err_raise(&err); } return obj; } static int load_options_cb(VALUE k, VALUE v, VALUE opts) { Options copts = (Options)opts; if (mode_sym == k) { if (object_sym == v) { copts->mode = ObjMode; } else if (optimized_sym == v) { copts->mode = ObjMode; } else if (generic_sym == v) { copts->mode = GenMode; } else if (limited_sym == v) { copts->mode = LimMode; } else if (hash_sym == v) { copts->mode = HashMode; } else if (hash_no_attrs_sym == v) { copts->mode = HashNoAttrMode; } else { rb_raise(ox_parse_error_class, ":mode must be :generic, :object, :limited, :hash, :hash_no_attrs.\n"); } } else if (effort_sym == k) { if (auto_define_sym == v) { copts->effort = AutoEffort; } else if (tolerant_sym == v) { copts->effort = TolerantEffort; } else if (strict_sym == v) { copts->effort = StrictEffort; } else { rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n"); } } else if (skip_sym == k) { if (skip_none_sym == v) { copts->skip = NoSkip; } else if (skip_off_sym == v) { copts->skip = OffSkip; } else if (skip_return_sym == v) { copts->skip = CrSkip; } else if (skip_white_sym == v) { copts->skip = SpcSkip; } else { rb_raise(ox_parse_error_class, ":skip must be :skip_none, :skip_return, :skip_white, or :skip_off.\n"); } } else if (trace_sym == k) { Check_Type(v, T_FIXNUM); copts->trace = FIX2INT(v); } else if (symbolize_keys_sym == k) { copts->sym_keys = (Qfalse == v) ? No : Yes; } else if (element_key_mod_sym == k) { copts->element_key_mod = v; } else if (attr_key_mod_sym == k) { copts->attr_key_mod = v; } else if (convert_special_sym == k) { copts->convert_special = (Qfalse != v); } else if (no_empty_sym == k) { copts->no_empty = (Qfalse != v); } else if (invalid_replace_sym == k) { if (Qnil == v) { copts->allow_invalid = Yes; } else { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(copts->inv_repl) - 2 < (size_t)slen) { rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.", (int)sizeof(copts->inv_repl) - 2); } strncpy(copts->inv_repl + 1, StringValuePtr(v), sizeof(copts->inv_repl) - 1); copts->inv_repl[sizeof(copts->inv_repl) - 1] = '\0'; *copts->inv_repl = (char)slen; copts->allow_invalid = No; } } else if (strip_namespace_sym == k) { if (Qfalse == v) { *copts->strip_ns = '\0'; } else if (Qtrue == v) { *copts->strip_ns = '*'; copts->strip_ns[1] = '\0'; } else if (Qnil != v) { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(copts->strip_ns) - 1 < (size_t)slen) { rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.", (int)sizeof(copts->strip_ns) - 1); } strncpy(copts->strip_ns, StringValuePtr(v), sizeof(copts->strip_ns) - 1); copts->strip_ns[sizeof(copts->strip_ns) - 1] = '\0'; } } else if (margin_sym == k) { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(copts->margin) - 1 < (size_t)slen) { rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.", (int)sizeof(copts->margin) - 1); } strncpy(copts->margin, StringValuePtr(v), sizeof(copts->margin) - 1); copts->margin[sizeof(copts->margin) - 1] = '\0'; copts->margin_len = strlen(copts->margin); } else if (with_cdata_sym == k) { copts->with_cdata = (Qtrue == v); } return ST_CONTINUE; } static VALUE load(char *xml, size_t len, int argc, VALUE *argv, VALUE self, VALUE encoding, Err err) { VALUE obj; struct _options options = ox_default_options; if (1 == argc && rb_cHash == rb_obj_class(*argv)) { rb_hash_foreach(*argv, load_options_cb, (VALUE)&options); } if ('\0' == *options.encoding) { if (Qnil != encoding) { options.rb_enc = rb_enc_from_index(rb_enc_get_index(encoding)); } else { options.rb_enc = 0; } } else if (0 == options.rb_enc) { options.rb_enc = rb_enc_find(options.encoding); } xml = defuse_bom(xml, &options); switch (options.mode) { case ObjMode: rb_gc_disable(); obj = ox_parse(xml, len, ox_obj_callbacks, 0, &options, err); RB_GC_GUARD(obj); rb_gc_enable(); break; case GenMode: obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err); break; case LimMode: obj = ox_parse(xml, len, ox_limited_callbacks, 0, &options, err); break; case HashMode: if (options.with_cdata) { obj = ox_parse(xml, len, ox_hash_cdata_callbacks, 0, &options, err); } else { obj = ox_parse(xml, len, ox_hash_callbacks, 0, &options, err); } break; case HashNoAttrMode: if (options.with_cdata) { obj = ox_parse(xml, len, ox_hash_no_attrs_cdata_callbacks, 0, &options, err); } else { obj = ox_parse(xml, len, ox_hash_no_attrs_callbacks, 0, &options, err); } break; case NoMode: obj = ox_parse(xml, len, ox_nomode_callbacks, 0, &options, err); break; default: obj = ox_parse(xml, len, ox_gen_callbacks, 0, &options, err); break; } return obj; } /* call-seq: load(xml, options) => Ox::Document or Ox::Element or Object * * Parses and XML document String into an Ox::Document, or Ox::Element, or * Object depending on the options. Raises an exception if the XML is malformed * or the classes specified are not valid. If a block is given it will be called * on the completion of each complete top level entity with that entity as it's * only argument. * * - +xml+ [String] XML String * - +options+ [Hash] load options * - *:mode* [:object|:generic|:limited] format expected * - _:object_ - object format * - _:generic_ - read as a generic XML file * - _:limited_ - read as a generic XML file but with callbacks on text and elements events only * - _:hash_ - read and convert to a Hash and core class objects only * - _:hash_no_attrs_ - read and convert to a Hash and core class objects only without capturing attributes * - *:effort* [:strict|:tolerant|:auto_define] effort to use when an undefined class is encountered, default: :strict * - _:strict_ - raise an NameError for missing classes and modules * - _:tolerant_ - return nil for missing classes and modules * - _:auto_define_ - auto define missing classes and modules * - *:trace* [Fixnum] trace level as a Fixnum, default: 0 (silent) * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace. * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped. * - *:with_cdata* [true|false] if true cdata is included in hash_load output otherwise it is not. */ static VALUE load_str(int argc, VALUE *argv, VALUE self) { char *xml; size_t len; VALUE obj; VALUE encoding; struct _err err; err_init(&err); Check_Type(*argv, T_STRING); /* the xml string gets modified so make a copy of it */ len = RSTRING_LEN(*argv) + 1; if (SMALL_XML < len) { xml = ALLOC_N(char, len); } else { xml = ALLOCA_N(char, len); } encoding = rb_obj_encoding(*argv); memcpy(xml, StringValuePtr(*argv), len); xml[len - 1] = '\0'; obj = load(xml, len - 1, argc - 1, argv + 1, self, encoding, &err); if (SMALL_XML < len) { xfree(xml); } if (err_has(&err)) { ox_err_raise(&err); } return obj; } /* call-seq: load_file(file_path, options) => Ox::Document or Ox::Element or Object * * Parses and XML document from a file into an Ox::Document, or Ox::Element, * or Object depending on the options. Raises an exception if the XML is * malformed or the classes specified are not valid. * - +file_path+ [String] file path to read the XML document from * - +options+ [Hash] load options * - *:mode* [:object|:generic|:limited] format expected * - _:object_ - object format * - _:generic_ - read as a generic XML file * - _:limited_ - read as a generic XML file but with callbacks on text and elements events only * - _:hash_ - read and convert to a Hash and core class objects only * - _:hash_no_attrs_ - read and convert to a Hash and core class objects only without capturing attributes * - *:effort* [:strict|:tolerant|:auto_define] effort to use when an undefined class is encountered, default: :strict * - _:strict_ - raise an NameError for missing classes and modules * - _:tolerant_ - return nil for missing classes and modules * - _:auto_define_ - auto define missing classes and modules * - *:trace* [Fixnum] trace level as a Fixnum, default: 0 (silent) * - *:symbolize_keys* [true|false|nil] symbolize element attribute keys or leave as Strings * - *:invalid_replace* [nil|String] replacement string for invalid XML characters on dump. nil indicates include * anyway as hex. A string, limited to 10 characters will replace the invalid character with the replace. * - *:strip_namespace* [String|true|false] "" or false result in no namespace stripping. A string of "*" or true will * strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped. */ static VALUE load_file(int argc, VALUE *argv, VALUE self) { char *path; char *xml; FILE *f; off_t len; VALUE obj; struct _err err; err_init(&err); Check_Type(*argv, T_STRING); path = StringValuePtr(*argv); if (0 == (f = fopen(path, "r"))) { rb_raise(rb_eIOError, "%s\n", strerror(errno)); } fseek(f, 0, SEEK_END); len = ftello(f); if (SMALL_XML < len) { xml = ALLOC_N(char, len + 1); } else { xml = ALLOCA_N(char, len + 1); } fseek(f, 0, SEEK_SET); if ((size_t)len != fread(xml, 1, len, f)) { ox_err_set(&err, rb_eLoadError, "Failed to read %ld bytes from %s.\n", (long)len, path); obj = Qnil; } else { xml[len] = '\0'; obj = load(xml, len, argc - 1, argv + 1, self, Qnil, &err); } fclose(f); if (SMALL_XML < len) { xfree(xml); } if (err_has(&err)) { ox_err_raise(&err); } return obj; } /* call-seq: sax_parse(handler, io, options) * * Parses an IO stream or file containing an XML document. Raises an exception * if the XML is malformed or the classes specified are not valid. * - +handler+ [Ox::Sax] SAX (responds to OX::Sax methods) like handler * - +io+ [IO|String] IO Object to read from * - +options+ [Hash] options parse options * - *:convert_special* [true|false] flag indicating special characters like < are converted * - *:symbolize* [true|false] flag indicating the parser symbolize element and attribute names * - *:smart* [true|false] flag indicating the parser uses hints if available (use with html) * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collpase white * space into a single space. Default (skip space) * - *:strip_namespace* [nil|String|true|false] "" or false result in no namespace stripping. A string of "*" or true * will strip all namespaces. Any other non-empty string indicates that matching namespaces will be stripped. */ static VALUE sax_parse(int argc, VALUE *argv, VALUE self) { struct _saxOptions options; options.symbolize = (No != ox_default_options.sym_keys); options.convert_special = ox_default_options.convert_special; options.smart = (Yes == ox_default_options.smart); options.skip = ox_default_options.skip; options.hints = NULL; strcpy(options.strip_ns, ox_default_options.strip_ns); if (argc < 2) { rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_parse.\n"); } if (3 <= argc && rb_cHash == rb_obj_class(argv[2])) { VALUE h = argv[2]; VALUE v; if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) { options.convert_special = (Qtrue == v); } if (Qnil != (v = rb_hash_lookup(h, smart_sym))) { options.smart = (Qtrue == v); } if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) { options.symbolize = (Qtrue == v); } if (Qnil != (v = rb_hash_lookup(h, skip_sym))) { if (skip_return_sym == v) { options.skip = CrSkip; } else if (skip_white_sym == v) { options.skip = SpcSkip; } else if (skip_none_sym == v) { options.skip = NoSkip; } else if (skip_off_sym == v) { options.skip = OffSkip; } } if (Qnil != (v = rb_hash_lookup(h, strip_namespace_sym))) { if (Qfalse == v) { *options.strip_ns = '\0'; } else if (Qtrue == v) { *options.strip_ns = '*'; options.strip_ns[1] = '\0'; } else { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(options.strip_ns) - 1 < (size_t)slen) { rb_raise(ox_parse_error_class, ":strip_namespace can be no longer than %d characters.", (int)sizeof(options.strip_ns) - 1); } strncpy(options.strip_ns, StringValuePtr(v), sizeof(options.strip_ns) - 1); options.strip_ns[sizeof(options.strip_ns) - 1] = '\0'; } } } ox_sax_parse(argv[0], argv[1], &options); return Qnil; } /* call-seq: sax_html(handler, io, options) * * Parses an IO stream or file containing an XML document. Raises an exception * if the XML is malformed or the classes specified are not valid. * - +handler+ [Ox::Sax] SAX (responds to OX::Sax methods) like handler * - +io+ [IO|String] IO Object to read from * - +options+ [Hash] options parse options * - *:convert_special* [true|false] flag indicating special characters like < are converted * - *:symbolize* [true|false] flag indicating the parser symbolize element and attribute names * - *:skip* [:skip_none|:skip_return|:skip_white|:skip_off] flag indicating the parser skips \\r or collapse white * space into a single space. Default (skip space) * - *:overlay* [Hash] a Hash of keys that match html element names and values that are one of * - _:active_ - make the normal callback for the element * - _:nest_ok_ - active but ignore nest check * - _:inactive_ - do not make the element start, end, or attribute callbacks for this element only * - _:block_ - block this and all children callbacks * - _:off_ - block this element and it's children unless the child element is active * - _:abort_ - abort the html processing and return */ static VALUE sax_html(int argc, VALUE *argv, VALUE self) { struct _saxOptions options; bool free_hints = false; options.symbolize = (No != ox_default_options.sym_keys); options.convert_special = ox_default_options.convert_special; options.smart = true; options.skip = ox_default_options.skip; options.hints = ox_default_options.html_hints; if (NULL == options.hints) { options.hints = ox_hints_html(); } *options.strip_ns = '\0'; if (argc < 2) { rb_raise(ox_parse_error_class, "Wrong number of arguments to sax_html.\n"); } if (3 <= argc && rb_cHash == rb_obj_class(argv[2])) { volatile VALUE h = argv[2]; volatile VALUE v; if (Qnil != (v = rb_hash_lookup(h, convert_special_sym))) { options.convert_special = (Qtrue == v); } if (Qnil != (v = rb_hash_lookup(h, symbolize_sym))) { options.symbolize = (Qtrue == v); } if (Qnil != (v = rb_hash_lookup(h, skip_sym))) { if (skip_return_sym == v) { options.skip = CrSkip; } else if (skip_white_sym == v) { options.skip = SpcSkip; } else if (skip_none_sym == v) { options.skip = NoSkip; } else if (skip_off_sym == v) { options.skip = OffSkip; } } if (Qnil != (v = rb_hash_lookup(h, overlay_sym))) { int cnt; Check_Type(v, T_HASH); cnt = (int)RHASH_SIZE(v); if (0 == cnt) { options.hints = ox_hints_html(); } else { options.hints = ox_hints_dup(options.hints); free_hints = true; rb_hash_foreach(v, set_overlay, (VALUE)options.hints); } } } ox_sax_parse(argv[0], argv[1], &options); if (free_hints) { ox_hints_destroy(options.hints); } return Qnil; } static void parse_dump_options(VALUE ropts, Options copts) { struct _yesNoOpt ynos[] = {{with_xml_sym, &copts->with_xml}, {with_dtd_sym, &copts->with_dtd}, {with_instruct_sym, &copts->with_instruct}, {xsd_date_sym, &copts->xsd_date}, {circular_sym, &copts->circular}, {Qnil, 0}}; YesNoOpt o; if (rb_cHash == rb_obj_class(ropts)) { VALUE v; if (Qnil != (v = rb_hash_lookup(ropts, ox_indent_sym))) { if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) { rb_raise(ox_parse_error_class, ":indent must be a Fixnum.\n"); } copts->indent = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(ropts, trace_sym))) { if (rb_cInteger != rb_obj_class(v) && T_FIXNUM != rb_type(v)) { rb_raise(ox_parse_error_class, ":trace must be a Fixnum.\n"); } copts->trace = NUM2INT(v); } if (Qnil != (v = rb_hash_lookup(ropts, ox_encoding_sym))) { if (rb_cString != rb_obj_class(v)) { rb_raise(ox_parse_error_class, ":encoding must be a String.\n"); } strncpy(copts->encoding, StringValuePtr(v), sizeof(copts->encoding) - 1); } if (Qnil != (v = rb_hash_lookup(ropts, no_empty_sym))) { copts->no_empty = (v == Qtrue); } if (Qnil != (v = rb_hash_lookup(ropts, effort_sym))) { if (auto_define_sym == v) { copts->effort = AutoEffort; } else if (tolerant_sym == v) { copts->effort = TolerantEffort; } else if (strict_sym == v) { copts->effort = StrictEffort; } else { rb_raise(ox_parse_error_class, ":effort must be :strict, :tolerant, or :auto_define.\n"); } } v = rb_hash_lookup(ropts, invalid_replace_sym); if (Qnil == v) { if (Qtrue == rb_funcall(ropts, has_key_id, 1, invalid_replace_sym)) { copts->allow_invalid = Yes; } } else { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(copts->inv_repl) - 2 < (size_t)slen) { rb_raise(ox_parse_error_class, ":invalid_replace can be no longer than %d characters.", (int)sizeof(copts->inv_repl) - 2); } strncpy(copts->inv_repl + 1, StringValuePtr(v), sizeof(copts->inv_repl) - 1); copts->inv_repl[sizeof(copts->inv_repl) - 1] = '\0'; *copts->inv_repl = (char)slen; copts->allow_invalid = No; } v = rb_hash_lookup(ropts, margin_sym); if (Qnil != v) { long slen; Check_Type(v, T_STRING); slen = RSTRING_LEN(v); if (sizeof(copts->margin) - 2 < (size_t)slen) { rb_raise(ox_parse_error_class, ":margin can be no longer than %d characters.", (int)sizeof(copts->margin) - 2); } strncpy(copts->margin, StringValuePtr(v), sizeof(copts->margin) - 1); copts->margin[sizeof(copts->margin) - 1] = '\0'; copts->margin_len = (char)slen; } for (o = ynos; 0 != o->attr; o++) { if (Qnil != (v = rb_hash_lookup(ropts, o->sym))) { VALUE c = rb_obj_class(v); if (rb_cTrueClass == c) { *o->attr = Yes; } else if (rb_cFalseClass == c) { *o->attr = No; } else { rb_raise(ox_parse_error_class, "%s must be true or false.\n", rb_id2name(SYM2ID(o->sym))); } } } } } /* call-seq: dump(obj, options) => xml-string * * Dumps an Object (obj) to a string. * - +obj+ [Object] Object to serialize as an XML document String * - +options+ [Hash] formating options * - *:indent* [Fixnum] format expected * - *:no_empty* [true|false] if true don't output empty elements * - *:xsd_date* [true|false] use XSD date format if true, default: false * - *:circular* [true|false] allow circular references, default: false * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: * :strict * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered * - _:tolerant_ - replaces undumplable objects with nil * * Note that an indent of less than zero will result in a tight one line output * unless the text in the XML fields contain new line characters. */ static VALUE dump(int argc, VALUE *argv, VALUE self) { char *xml; struct _options copts = ox_default_options; VALUE rstr; if (2 == argc) { parse_dump_options(argv[1], &copts); } if (0 == (xml = ox_write_obj_to_str(*argv, &copts))) { rb_raise(rb_eNoMemError, "Not enough memory.\n"); } rstr = rb_str_new2(xml); if ('\0' != *copts.encoding) { rb_enc_associate(rstr, rb_enc_find(copts.encoding)); } xfree(xml); return rstr; } /* call-seq: to_xml(obj, options) => xml-string * * Dumps an Object (obj) to a string. * - +obj+ [Object] Object to serialize as an XML document String * - +options+ [Hash] formating options * - *:indent* [Fixnum] format expected * - *:no_empty* [true|false] if true don't output empty elements * - *:xsd_date* [true|false] use XSD date format if true, default: false * - *:circular* [true|false] allow circular references, default: false * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: * :strict * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered * - _:tolerant_ - replaces undumplable objects with nil * * Note that an indent of less than zero will result in a tight one line output * unless the text in the XML fields contain new line characters. */ static VALUE to_xml(int argc, VALUE *argv, VALUE self) { return dump(argc, argv, self); } /* call-seq: to_file(file_path, obj, options) => Object * * Dumps an Object to the specified file. * - +file_path+ [String] file path to write the XML document to * - +obj+ [Object] Object to serialize as an XML document String * - +options+ [Hash] formating options * - *:indent* [Fixnum] format expected * - *:xsd_date* [true|false] use XSD date format if true, default: false * - *:circular* [true|false] allow circular references, default: false * - *:strict|:tolerant]* [ :effort effort to use when an undumpable object (e.g., IO) is encountered, default: * :strict * - _:strict_ - raise an NotImplementedError if an undumpable object is encountered * - _:tolerant_ - replaces undumplable objects with nil * * Note that an indent of less than zero will result in a tight one line output * unless the text in the XML fields contain new line characters. */ static VALUE to_file(int argc, VALUE *argv, VALUE self) { struct _options copts = ox_default_options; if (3 == argc) { parse_dump_options(argv[2], &copts); } Check_Type(*argv, T_STRING); ox_write_obj_to_file(argv[1], StringValuePtr(*argv), &copts); return Qnil; } #if WITH_CACHE_TESTS extern void ox_cache_test(void); static VALUE cache_test(VALUE self) { ox_cache_test(); return Qnil; } extern void ox_cache8_test(void); static VALUE cache8_test(VALUE self) { ox_cache8_test(); return Qnil; } #endif void Init_ox() { #if HAVE_RB_EXT_RACTOR_SAFE rb_ext_ractor_safe(true); #endif Ox = rb_define_module("Ox"); rb_define_module_function(Ox, "default_options", get_def_opts, 0); rb_define_module_function(Ox, "default_options=", set_def_opts, 1); rb_define_module_function(Ox, "parse_obj", to_obj, 1); rb_define_module_function(Ox, "parse", to_gen, 1); rb_define_module_function(Ox, "load", load_str, -1); rb_define_module_function(Ox, "sax_parse", sax_parse, -1); rb_define_module_function(Ox, "sax_html", sax_html, -1); rb_define_module_function(Ox, "to_xml", to_xml, -1); rb_define_module_function(Ox, "dump", dump, -1); rb_define_module_function(Ox, "load_file", load_file, -1); rb_define_module_function(Ox, "to_file", to_file, -1); rb_define_module_function(Ox, "sax_html_overlay", sax_html_overlay, 0); ox_init_builder(Ox); rb_require("time"); rb_require("date"); rb_require("bigdecimal"); rb_require("stringio"); ox_abort_id = rb_intern("abort"); ox_at_column_id = rb_intern("@column"); ox_at_content_id = rb_intern("@content"); ox_at_id = rb_intern("at"); ox_at_line_id = rb_intern("@line"); ox_at_pos_id = rb_intern("@pos"); ox_at_value_id = rb_intern("@value"); ox_attr_id = rb_intern("attr"); ox_attr_value_id = rb_intern("attr_value"); ox_attributes_id = rb_intern("@attributes"); ox_attrs_done_id = rb_intern("attrs_done"); ox_beg_id = rb_intern("@beg"); ox_bigdecimal_id = rb_intern("BigDecimal"); ox_call_id = rb_intern("call"); ox_cdata_id = rb_intern("cdata"); ox_comment_id = rb_intern("comment"); ox_den_id = rb_intern("@den"); ox_doctype_id = rb_intern("doctype"); ox_end_element_id = rb_intern("end_element"); ox_end_id = rb_intern("@end"); ox_end_instruct_id = rb_intern("end_instruct"); ox_error_id = rb_intern("error"); ox_excl_id = rb_intern("@excl"); ox_external_encoding_id = rb_intern("external_encoding"); ox_fileno_id = rb_intern("fileno"); ox_force_encoding_id = rb_intern("force_encoding"); ox_inspect_id = rb_intern("inspect"); ox_instruct_id = rb_intern("instruct"); ox_jd_id = rb_intern("jd"); ox_keys_id = rb_intern("keys"); ox_local_id = rb_intern("local"); ox_mesg_id = rb_intern("mesg"); ox_message_id = rb_intern("message"); ox_nodes_id = rb_intern("@nodes"); ox_new_id = rb_intern("new"); ox_num_id = rb_intern("@num"); ox_parse_id = rb_intern("parse"); ox_pos_id = rb_intern("pos"); ox_read_id = rb_intern("read"); ox_readpartial_id = rb_intern("readpartial"); ox_start_element_id = rb_intern("start_element"); ox_string_id = rb_intern("string"); ox_text_id = rb_intern("text"); ox_to_c_id = rb_intern("to_c"); ox_value_id = rb_intern("value"); encoding_id = rb_intern("encoding"); has_key_id = rb_intern("has_key?"); rb_require("ox/version"); rb_require("ox/error"); rb_require("ox/hasattrs"); rb_require("ox/node"); rb_require("ox/comment"); rb_require("ox/instruct"); rb_require("ox/cdata"); rb_require("ox/doctype"); rb_require("ox/element"); rb_require("ox/document"); rb_require("ox/bag"); rb_require("ox/sax"); ox_time_class = rb_const_get(rb_cObject, rb_intern("Time")); ox_date_class = rb_const_get(rb_cObject, rb_intern("Date")); ox_parse_error_class = rb_const_get_at(Ox, rb_intern("ParseError")); ox_syntax_error_class = rb_const_get_at(Ox, rb_intern("SyntaxError")); ox_arg_error_class = rb_const_get_at(Ox, rb_intern("ArgError")); ox_struct_class = rb_const_get(rb_cObject, rb_intern("Struct")); ox_stringio_class = rb_const_get(rb_cObject, rb_intern("StringIO")); ox_bigdecimal_class = rb_const_get(rb_cObject, rb_intern("BigDecimal")); abort_sym = ID2SYM(rb_intern("abort")); rb_gc_register_address(&abort_sym); active_sym = ID2SYM(rb_intern("active")); rb_gc_register_address(&active_sym); attr_key_mod_sym = ID2SYM(rb_intern("attr_key_mod")); rb_gc_register_address(&attr_key_mod_sym); auto_define_sym = ID2SYM(rb_intern("auto_define")); rb_gc_register_address(&auto_define_sym); auto_sym = ID2SYM(rb_intern("auto")); rb_gc_register_address(&auto_sym); block_sym = ID2SYM(rb_intern("block")); rb_gc_register_address(&block_sym); circular_sym = ID2SYM(rb_intern("circular")); rb_gc_register_address(&circular_sym); convert_special_sym = ID2SYM(rb_intern("convert_special")); rb_gc_register_address(&convert_special_sym); effort_sym = ID2SYM(rb_intern("effort")); rb_gc_register_address(&effort_sym); element_key_mod_sym = ID2SYM(rb_intern("element_key_mod")); rb_gc_register_address(&element_key_mod_sym); generic_sym = ID2SYM(rb_intern("generic")); rb_gc_register_address(&generic_sym); hash_no_attrs_sym = ID2SYM(rb_intern("hash_no_attrs")); rb_gc_register_address(&hash_no_attrs_sym); hash_sym = ID2SYM(rb_intern("hash")); rb_gc_register_address(&hash_sym); inactive_sym = ID2SYM(rb_intern("inactive")); rb_gc_register_address(&inactive_sym); invalid_replace_sym = ID2SYM(rb_intern("invalid_replace")); rb_gc_register_address(&invalid_replace_sym); limited_sym = ID2SYM(rb_intern("limited")); rb_gc_register_address(&limited_sym); margin_sym = ID2SYM(rb_intern("margin")); rb_gc_register_address(&margin_sym); mode_sym = ID2SYM(rb_intern("mode")); rb_gc_register_address(&mode_sym); nest_ok_sym = ID2SYM(rb_intern("nest_ok")); rb_gc_register_address(&nest_ok_sym); no_empty_sym = ID2SYM(rb_intern("no_empty")); rb_gc_register_address(&no_empty_sym); object_sym = ID2SYM(rb_intern("object")); rb_gc_register_address(&object_sym); off_sym = ID2SYM(rb_intern("off")); rb_gc_register_address(&off_sym); opt_format_sym = ID2SYM(rb_intern("opt_format")); rb_gc_register_address(&opt_format_sym); optimized_sym = ID2SYM(rb_intern("optimized")); rb_gc_register_address(&optimized_sym); overlay_sym = ID2SYM(rb_intern("overlay")); rb_gc_register_address(&overlay_sym); ox_encoding_sym = ID2SYM(rb_intern("encoding")); rb_gc_register_address(&ox_encoding_sym); ox_indent_sym = ID2SYM(rb_intern("indent")); rb_gc_register_address(&ox_indent_sym); ox_size_sym = ID2SYM(rb_intern("size")); rb_gc_register_address(&ox_size_sym); ox_standalone_sym = ID2SYM(rb_intern("standalone")); rb_gc_register_address(&ox_standalone_sym); ox_version_sym = ID2SYM(rb_intern("version")); rb_gc_register_address(&ox_version_sym); skip_none_sym = ID2SYM(rb_intern("skip_none")); rb_gc_register_address(&skip_none_sym); skip_off_sym = ID2SYM(rb_intern("skip_off")); rb_gc_register_address(&skip_off_sym); skip_return_sym = ID2SYM(rb_intern("skip_return")); rb_gc_register_address(&skip_return_sym); skip_sym = ID2SYM(rb_intern("skip")); rb_gc_register_address(&skip_sym); skip_white_sym = ID2SYM(rb_intern("skip_white")); rb_gc_register_address(&skip_white_sym); smart_sym = ID2SYM(rb_intern("smart")); rb_gc_register_address(&smart_sym); strict_sym = ID2SYM(rb_intern("strict")); rb_gc_register_address(&strict_sym); strip_namespace_sym = ID2SYM(rb_intern("strip_namespace")); rb_gc_register_address(&strip_namespace_sym); symbolize_keys_sym = ID2SYM(rb_intern("symbolize_keys")); rb_gc_register_address(&symbolize_keys_sym); symbolize_sym = ID2SYM(rb_intern("symbolize")); rb_gc_register_address(&symbolize_sym); tolerant_sym = ID2SYM(rb_intern("tolerant")); rb_gc_register_address(&tolerant_sym); trace_sym = ID2SYM(rb_intern("trace")); rb_gc_register_address(&trace_sym); with_cdata_sym = ID2SYM(rb_intern("with_cdata")); rb_gc_register_address(&with_cdata_sym); with_dtd_sym = ID2SYM(rb_intern("with_dtd")); rb_gc_register_address(&with_dtd_sym); with_instruct_sym = ID2SYM(rb_intern("with_instructions")); rb_gc_register_address(&with_instruct_sym); with_xml_sym = ID2SYM(rb_intern("with_xml")); rb_gc_register_address(&with_xml_sym); xsd_date_sym = ID2SYM(rb_intern("xsd_date")); rb_gc_register_address(&xsd_date_sym); ox_empty_string = rb_str_new2(""); rb_gc_register_address(&ox_empty_string); ox_zero_fixnum = INT2NUM(0); rb_gc_register_address(&ox_zero_fixnum); ox_sym_bank = rb_ary_new(); rb_gc_register_address(&ox_sym_bank); ox_document_clas = rb_const_get_at(Ox, rb_intern("Document")); ox_element_clas = rb_const_get_at(Ox, rb_intern("Element")); ox_instruct_clas = rb_const_get_at(Ox, rb_intern("Instruct")); ox_comment_clas = rb_const_get_at(Ox, rb_intern("Comment")); ox_raw_clas = rb_const_get_at(Ox, rb_intern("Raw")); ox_doctype_clas = rb_const_get_at(Ox, rb_intern("DocType")); ox_cdata_clas = rb_const_get_at(Ox, rb_intern("CData")); ox_bag_clas = rb_const_get_at(Ox, rb_intern("Bag")); // Classes can move in more recent versions so register them all. rb_gc_register_address(&Ox); rb_gc_register_address(&ox_arg_error_class); rb_gc_register_address(&ox_bag_clas); rb_gc_register_address(&ox_bag_clas); rb_gc_register_address(&ox_bigdecimal_class); rb_gc_register_address(&ox_cdata_clas); rb_gc_register_address(&ox_cdata_clas); rb_gc_register_address(&ox_comment_clas); rb_gc_register_address(&ox_comment_clas); rb_gc_register_address(&ox_date_class); rb_gc_register_address(&ox_doctype_clas); rb_gc_register_address(&ox_doctype_clas); rb_gc_register_address(&ox_document_clas); rb_gc_register_address(&ox_document_clas); rb_gc_register_address(&ox_element_clas); rb_gc_register_address(&ox_element_clas); rb_gc_register_address(&ox_encoding_sym); rb_gc_register_address(&ox_indent_sym); rb_gc_register_address(&ox_instruct_clas); rb_gc_register_address(&ox_instruct_clas); rb_gc_register_address(&ox_parse_error_class); rb_gc_register_address(&ox_raw_clas); rb_gc_register_address(&ox_raw_clas); rb_gc_register_address(&ox_size_sym); rb_gc_register_address(&ox_standalone_sym); rb_gc_register_address(&ox_stringio_class); rb_gc_register_address(&ox_struct_class); rb_gc_register_address(&ox_syntax_error_class); rb_gc_register_address(&ox_time_class); rb_gc_register_address(&ox_version_sym); slot_cache_new(&ox_class_cache); ox_sax_define(); ox_hash_init(); #if WITH_CACHE_TESTS // space added to stop yardoc from trying to document rb_define _module_function(Ox, "cache_test", cache_test, 0); rb_define _module_function(Ox, "cache8_test", cache8_test, 0); #endif ox_utf8_encoding = rb_enc_find("UTF-8"); } #if __GNUC__ > 4 _Noreturn void #else void #endif _ox_raise_error(const char *msg, const char *xml, const char *current, const char *file, int line) { int xline = 1; int col = 1; for (; xml < current && '\n' != *current; current--) { col++; } for (; xml < current; current--) { if ('\n' == *current) { xline++; } } rb_gc_enable(); rb_raise(ox_parse_error_class, "%s at line %d, column %d [%s:%d]\n", msg, xline, col, file, line); } ox-2.14.17/ext/ox/ox.h000066400000000000000000000155301445411231300143430ustar00rootroot00000000000000/* ox.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_H #define OX_H #if defined(__cplusplus) extern "C" { #if 0 } /* satisfy cc-mode */ #endif #endif #define RSTRING_NOT_MODIFIED #include "ruby.h" #include "ruby/encoding.h" #if HAVE_RUBY_ST_H #include "ruby/st.h" #else // Only on travis, local is where it is for all others. Seems to vary depending on the travis machine picked up. #include "st.h" #endif #include "attr.h" #include "err.h" #include "helper.h" #include "slotcache.h" #include "type.h" #define raise_error(msg, xml, current) _ox_raise_error(msg, xml, current, __FILE__, __LINE__) #define MAX_TEXT_LEN 4096 #define SILENT 0 #define TRACE 1 #define DEBUG 2 #define XSD_DATE 0x0001 #define WITH_XML 0x0002 #define WITH_INST 0x0004 #define WITH_DTD 0x0008 #define CIRCULAR 0x0010 #define XSD_DATE_SET 0x0100 #define WITH_XML_SET 0x0200 #define WITH_INST_SET 0x0400 #define WITH_DTD_SET 0x0800 #define CIRCULAR_SET 0x1000 typedef enum { UseObj = 1, UseAttr = 2, UseAttrSet = 3, UseArray = 4, UseAMember = 5, UseHash = 6, UseHashKey = 7, UseHashVal = 8, UseRange = 9, UseRangeAttr = 10, UseRaw = 11, } Use; typedef enum { StrictEffort = 's', TolerantEffort = 't', AutoEffort = 'a', NoEffort = 0, } Effort; typedef enum { Yes = 'y', No = 'n', NotSet = 0 } YesNo; typedef enum { ObjMode = 'o', GenMode = 'g', LimMode = 'l', HashMode = 'h', HashNoAttrMode = 'n', NoMode = 0 } LoadMode; typedef enum { OffSkip = 'o', NoSkip = 'n', CrSkip = 'r', SpcSkip = 's', } SkipMode; typedef struct _pInfo *PInfo; typedef struct _parseCallbacks { void (*instruct)(PInfo pi, const char *target, Attr attrs, const char *content); void (*add_doctype)(PInfo pi, const char *docType); void (*add_comment)(PInfo pi, const char *comment); void (*add_cdata)(PInfo pi, const char *cdata, size_t len); void (*add_text)(PInfo pi, char *text, int closed); void (*add_element)(PInfo pi, const char *ename, Attr attrs, int hasChildren); void (*end_element)(PInfo pi, const char *ename); void (*finish)(PInfo pi); } *ParseCallbacks; typedef struct _circArray { VALUE obj_array[1024]; VALUE *objs; unsigned long size; /* allocated size or initial array size */ unsigned long cnt; } *CircArray; typedef struct _options { char encoding[64]; // encoding, stored in the option to avoid GC invalidation in default values char margin[128]; // left margin for dumping int indent; // indention for dump, default 2 int trace; // trace level char margin_len; // margin length char with_dtd; // YesNo char with_xml; // YesNo char with_instruct; // YesNo char circular; // YesNo char xsd_date; // YesNo char mode; // LoadMode char effort; // Effort char sym_keys; // symbolize keys char skip; // skip mode char smart; // YesNo sax smart mode char convert_special; // boolean true or false char allow_invalid; // YesNo char no_empty; // boolean - no empty elements when dumping char with_cdata; // boolean - hash_load should include cdata char inv_repl[12]; // max 10 valid characters, first character is the length char strip_ns[64]; // namespace to strip, \0 is no-strip, \* is all, else only matches struct _hints *html_hints; // html hints VALUE attr_key_mod; VALUE element_key_mod; rb_encoding *rb_enc; } *Options; // parse information structure struct _pInfo { struct _helperStack helpers; struct _err err; char *str; // buffer being read from char *end; // end of original string char *s; // current position in buffer VALUE obj; ParseCallbacks pcb; CircArray circ_array; unsigned long id; // set for text types when cirs_array is set Options options; VALUE *marked; int mark_size; // allocated size int mark_cnt; char last; // last character read, rarely set }; extern VALUE ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options, Err err); extern void _ox_raise_error(const char *msg, const char *xml, const char *current, const char *file, int line); extern void ox_sax_define(void); extern char *ox_write_obj_to_str(VALUE obj, Options copts); extern void ox_write_obj_to_file(VALUE obj, const char *path, Options copts); extern struct _options ox_default_options; extern VALUE Ox; extern ID ox_abort_id; extern ID ox_at_column_id; extern ID ox_at_content_id; extern ID ox_at_id; extern ID ox_at_line_id; extern ID ox_at_pos_id; extern ID ox_at_value_id; extern ID ox_attr_id; extern ID ox_attr_value_id; extern ID ox_attrs_done_id; extern ID ox_attributes_id; extern ID ox_beg_id; extern ID ox_bigdecimal_id; extern ID ox_call_id; extern ID ox_cdata_id; extern ID ox_comment_id; extern ID ox_den_id; extern ID ox_doctype_id; extern ID ox_end_element_id; extern ID ox_end_id; extern ID ox_end_instruct_id; extern ID ox_error_id; extern ID ox_excl_id; extern ID ox_external_encoding_id; extern ID ox_fileno_id; extern ID ox_force_encoding_id; extern ID ox_inspect_id; extern ID ox_instruct_id; extern ID ox_jd_id; extern ID ox_keys_id; extern ID ox_local_id; extern ID ox_mesg_id; extern ID ox_message_id; extern ID ox_new_id; extern ID ox_nodes_id; extern ID ox_num_id; extern ID ox_parse_id; extern ID ox_pos_id; extern ID ox_read_id; extern ID ox_readpartial_id; extern ID ox_start_element_id; extern ID ox_string_id; extern ID ox_text_id; extern ID ox_to_c_id; extern ID ox_value_id; extern rb_encoding *ox_utf8_encoding; extern VALUE ox_empty_string; extern VALUE ox_encoding_sym; extern VALUE ox_indent_sym; extern VALUE ox_size_sym; extern VALUE ox_standalone_sym; extern VALUE ox_sym_bank; // Array extern VALUE ox_version_sym; extern VALUE ox_zero_fixnum; extern VALUE ox_bigdecimal_class; extern VALUE ox_date_class; extern VALUE ox_stringio_class; extern VALUE ox_struct_class; extern VALUE ox_time_class; extern VALUE ox_document_clas; extern VALUE ox_element_clas; extern VALUE ox_instruct_clas; extern VALUE ox_bag_clas; extern VALUE ox_comment_clas; extern VALUE ox_raw_clas; extern VALUE ox_doctype_clas; extern VALUE ox_cdata_clas; extern SlotCache ox_class_cache; extern void ox_init_builder(VALUE ox); #if defined(__cplusplus) #if 0 { /* satisfy cc-mode */ #endif } /* extern "C" { */ #endif #endif /* OX_H */ ox-2.14.17/ext/ox/parse.c000066400000000000000000001065451445411231300150310ustar00rootroot00000000000000/* parse.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include #include "attr.h" #include "err.h" #include "helper.h" #include "intern.h" #include "ox.h" #include "ruby.h" #include "special.h" static void read_instruction(PInfo pi); static void read_doctype(PInfo pi); static void read_comment(PInfo pi); static char *read_element(PInfo pi); static void read_text(PInfo pi); /*static void read_reduced_text(PInfo pi); */ static void read_cdata(PInfo pi); static char *read_name_token(PInfo pi); static char *read_quoted_value(PInfo pi); static char *read_hex_uint64(char *b, uint64_t *up); static char *read_10_uint64(char *b, uint64_t *up); static char *read_coded_chars(PInfo pi, char *text); static void next_non_white(PInfo pi); static int collapse_special(PInfo pi, char *str); /* This XML parser is a single pass, destructive, callback parser. It is a * single pass parse since it only make one pass over the characters in the * XML document string. It is destructive because it re-uses the content of * the string for values in the callback and places \0 characters at various * places to mark the end of tokens and strings. It is a callback parser like * a SAX parser because it uses callback when document elements are * encountered. * * Parsing is very tolerant. Lack of headers and even mispelled element * endings are passed over without raising an error. A best attempt is made in * all cases to parse the string. */ static char xml_valid_lower_chars[34] = "xxxxxxxxxooxxoxxxxxxxxxxxxxxxxxxo"; inline static int is_white(char c) { switch (c) { case ' ': case '\t': case '\f': case '\n': case '\r': return 1; default: return 0; } } inline static void next_non_white(PInfo pi) { for (; 1; pi->s++) { switch (*pi->s) { case ' ': case '\t': case '\f': case '\n': case '\r': break; default: return; } } } inline static void next_white(PInfo pi) { for (; 1; pi->s++) { switch (*pi->s) { case ' ': case '\t': case '\f': case '\n': case '\r': case '\0': return; default: break; } } } static void fix_newlines(char *buf) { #if HAVE_INDEX if (NULL != index(buf, '\r')) { #endif char *s = buf; char *d = buf; for (; '\0' != *s; s++) { if ('\r' == *s) { if ('\n' == *(s + 1)) { continue; } *d = '\n'; } else if (d < s) { *d = *s; } d++; } *d = '\0'; #if HAVE_INDEX } #endif } static void mark_pi_cb(void *ptr) { if (NULL != ptr) { HelperStack stack = &((PInfo)ptr)->helpers; Helper h; for (h = stack->head; h < stack->tail; h++) { if (NoCode != h->type) { rb_gc_mark(h->obj); } } } } VALUE ox_parse(char *xml, size_t len, ParseCallbacks pcb, char **endp, Options options, Err err) { struct _pInfo pi; int body_read = 0; int block_given = rb_block_given_p(); volatile VALUE wrap; if (0 == xml) { set_error(err, "Invalid arg, xml string can not be null", xml, 0); return Qnil; } if (DEBUG <= options->trace) { printf("Parsing xml:\n%s\n", xml); } // initialize parse info helper_stack_init(&pi.helpers); // Protect against GC wrap = Data_Wrap_Struct(rb_cObject, mark_pi_cb, NULL, &pi); err_init(&pi.err); pi.str = xml; pi.end = pi.str + len; pi.s = xml; pi.pcb = pcb; pi.obj = Qnil; pi.circ_array = 0; pi.options = options; pi.marked = NULL; pi.mark_size = 0; pi.mark_cnt = 0; while (1) { next_non_white(&pi); // skip white space if ('\0' == *pi.s) { break; } if (body_read && 0 != endp) { *endp = pi.s; break; } if ('<' != *pi.s) { // all top level entities start with < set_error(err, "invalid format, expected <", pi.str, pi.s); helper_stack_cleanup(&pi.helpers); return Qnil; } pi.s++; // past < switch (*pi.s) { case '?': // processing instruction pi.s++; read_instruction(&pi); break; case '!': // comment or doctype pi.s++; if ('\0' == *pi.s) { set_error(err, "invalid format, DOCTYPE or comment not terminated", pi.str, pi.s); helper_stack_cleanup(&pi.helpers); return Qnil; } else if ('-' == *pi.s) { pi.s++; // skip - if ('-' != *pi.s) { set_error(err, "invalid format, bad comment format", pi.str, pi.s); helper_stack_cleanup(&pi.helpers); return Qnil; } else { pi.s++; // skip second - read_comment(&pi); } } else if ((TolerantEffort == options->effort) ? 0 == strncasecmp("DOCTYPE", pi.s, 7) : 0 == strncmp("DOCTYPE", pi.s, 7)) { pi.s += 7; read_doctype(&pi); } else { set_error(err, "invalid format, DOCTYPE or comment expected", pi.str, pi.s); helper_stack_cleanup(&pi.helpers); return Qnil; } break; case '\0': set_error(err, "invalid format, document not terminated", pi.str, pi.s); helper_stack_cleanup(&pi.helpers); return Qnil; default: read_element(&pi); body_read = 1; break; } if (err_has(&pi.err)) { *err = pi.err; helper_stack_cleanup(&pi.helpers); return Qnil; } if (block_given && Qnil != pi.obj && Qundef != pi.obj) { if (NULL != pcb->finish) { pcb->finish(&pi); } rb_yield(pi.obj); } } DATA_PTR(wrap) = NULL; helper_stack_cleanup(&pi.helpers); if (NULL != pcb->finish) { pcb->finish(&pi); } return pi.obj; } // Entered after the "s; for (; true; pi->s++) { switch (*pi->s) { case '?': if ('>' == *(pi->s + 1)) { pi->s++; goto DONE; } break; case '\0': set_error(&pi->err, "processing instruction not terminated", pi->str, pi->s); return; default: break; } } DONE: cend = pi->s; size = cend - end - 1; pi->s = end; if (size < sizeof(content)) { content_ptr = content; } else { content_ptr = ALLOC_N(char, size + 1); } memcpy(content_ptr, end, size); content_ptr[size] = '\0'; next_non_white(pi); c = *pi->s; *end = '\0'; // terminate name if ('?' != c) { while ('?' != c) { pi->last = 0; if ('\0' == *pi->s) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, processing instruction not terminated", pi->str, pi->s); return; } next_non_white(pi); if (0 == (attr_name = read_name_token(pi))) { attr_stack_cleanup(&attrs); return; } end = pi->s; next_non_white(pi); if ('=' != *pi->s++) { attrs_ok = false; break; } *end = '\0'; // terminate name // read value next_non_white(pi); if (0 == (attr_value = read_quoted_value(pi))) { attr_stack_cleanup(&attrs); return; } attr_stack_push(&attrs, attr_name, attr_value); next_non_white(pi); if ('\0' == pi->last) { c = *pi->s; } else { c = pi->last; } } if ('?' == *pi->s) { pi->s++; } } else { pi->s++; } if (attrs_ok) { if ('>' != *pi->s++) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, processing instruction not terminated", pi->str, pi->s); return; } } else { pi->s = cend + 1; } if (0 != pi->pcb->instruct) { if (attrs_ok) { pi->pcb->instruct(pi, target, attrs.head, 0); } else { pi->pcb->instruct(pi, target, attrs.head, content_ptr); } } attr_stack_cleanup(&attrs); if (content_ptr != content) { xfree(content_ptr); } } static void read_delimited(PInfo pi, char end) { char c; if ('"' == end || '\'' == end) { for (c = *pi->s++; end != c; c = *pi->s++) { if ('\0' == c) { set_error(&pi->err, "invalid format, dectype not terminated", pi->str, pi->s); return; } } } else { while (1) { c = *pi->s++; if (end == c) { return; } switch (c) { case '\0': set_error(&pi->err, "invalid format, dectype not terminated", pi->str, pi->s); return; case '"': read_delimited(pi, c); break; case '\'': read_delimited(pi, c); break; case '[': read_delimited(pi, ']'); break; case '<': read_delimited(pi, '>'); break; default: break; } } } } // Entered after the "s; read_delimited(pi, '>'); if (err_has(&pi->err)) { return; } pi->s--; *pi->s = '\0'; pi->s++; if (0 != pi->pcb->add_doctype) { fix_newlines(doctype); pi->pcb->add_doctype(pi, doctype); } } // Entered after ""); if (0 == end) { set_error(&pi->err, "invalid format, comment not terminated", pi->str, pi->s); return; } for (s = end - 1; pi->s < s && !done; s--) { switch (*s) { case ' ': case '\t': case '\f': case '\n': case '\r': break; default: *(s + 1) = '\0'; done = 1; break; } } *end = '\0'; // in case the comment was blank pi->s = end + 3; if (0 != pi->pcb->add_comment) { fix_newlines(comment); pi->pcb->add_comment(pi, comment); } } // Entered after the '<' and the first character after that. Returns stat // code. static char *read_element(PInfo pi) { struct _attrStack attrs; const char *attr_name; const char *attr_value; char *name; char *ename; char *end; char c; long elen; int hasChildren = 0; int done = 0; attr_stack_init(&attrs); if (0 == (ename = read_name_token(pi))) { return 0; } end = pi->s; elen = end - ename; next_non_white(pi); c = *pi->s; *end = '\0'; if ('/' == c) { // empty element, no attributes and no children pi->s++; if ('>' != *pi->s) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, element not closed", pi->str, pi->s); return 0; } pi->s++; /* past > */ pi->pcb->add_element(pi, ename, attrs.head, hasChildren); pi->pcb->end_element(pi, ename); attr_stack_cleanup(&attrs); return 0; } /* read attribute names until the close (/ or >) is reached */ while (!done) { if ('\0' == c) { if (pi->end <= pi->s) { break; } next_non_white(pi); c = *pi->s; } pi->last = 0; switch (c) { case '\0': attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; case '/': /* Element with just attributes. */ pi->s++; if ('>' != *pi->s) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, element not closed", pi->str, pi->s); return 0; } pi->s++; pi->pcb->add_element(pi, ename, attrs.head, hasChildren); pi->pcb->end_element(pi, ename); attr_stack_cleanup(&attrs); return 0; case '>': /* has either children or a value */ pi->s++; hasChildren = 1; done = 1; pi->pcb->add_element(pi, ename, attrs.head, hasChildren); break; default: /* Attribute name so it's an element and the attribute will be */ /* added to it. */ if (0 == (attr_name = read_name_token(pi))) { attr_stack_cleanup(&attrs); return 0; } end = pi->s; next_non_white(pi); if ('=' != *pi->s++) { if (TolerantEffort == pi->options->effort) { pi->s--; pi->last = *pi->s; *end = '\0'; /* terminate name */ attr_value = ""; attr_stack_push(&attrs, attr_name, attr_value); break; } else { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, no attribute value", pi->str, pi->s); return 0; } } *end = '\0'; /* terminate name */ /* read value */ next_non_white(pi); if (0 == (attr_value = read_quoted_value(pi))) { return 0; } if (pi->options->convert_special && 0 != strchr(attr_value, '&')) { if (0 != collapse_special(pi, (char *)attr_value) || err_has(&pi->err)) { attr_stack_cleanup(&attrs); return 0; } } attr_stack_push(&attrs, attr_name, attr_value); break; } if ('\0' == pi->last) { c = '\0'; } else { c = pi->last; pi->last = '\0'; } } if (hasChildren) { char *start; int first = 1; done = 0; /* read children */ while (!done) { start = pi->s; next_non_white(pi); if (OffSkip == pi->options->skip && start < pi->s && '<' == *pi->s) { c = *pi->s; *pi->s = '\0'; pi->pcb->add_text(pi, start, 1); *pi->s = c; } c = *pi->s++; if ('\0' == c) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; } if ('<' == c) { char *slash; switch (*pi->s) { case '!': /* better be a comment or CDATA */ pi->s++; if ('-' == *pi->s && '-' == *(pi->s + 1)) { pi->s += 2; read_comment(pi); } else if ((TolerantEffort == pi->options->effort) ? 0 == strncasecmp("[CDATA[", pi->s, 7) : 0 == strncmp("[CDATA[", pi->s, 7)) { pi->s += 7; read_cdata(pi); } else { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, invalid comment or CDATA format", pi->str, pi->s); return 0; } break; case '?': /* processing instruction */ pi->s++; read_instruction(pi); break; case '/': slash = pi->s; pi->s++; if (0 == (name = read_name_token(pi))) { attr_stack_cleanup(&attrs); return 0; } end = pi->s; next_non_white(pi); c = *pi->s; *end = '\0'; if (0 != ((TolerantEffort == pi->options->effort) ? strcasecmp(name, ename) : strcmp(name, ename))) { attr_stack_cleanup(&attrs); if (TolerantEffort == pi->options->effort) { pi->pcb->end_element(pi, ename); return name; } else { set_error(&pi->err, "invalid format, elements overlap", pi->str, pi->s); return 0; } } if ('>' != c) { attr_stack_cleanup(&attrs); set_error(&pi->err, "invalid format, element not closed", pi->str, pi->s); return 0; } if (first && start != slash - 1) { // Some white space between start and here so add as // text after checking skip. *(slash - 1) = '\0'; switch (pi->options->skip) { case CrSkip: { char *s = start; char *e = start; for (; '\0' != *e; e++) { if ('\r' != *e) { *s++ = *e; } } *s = '\0'; break; } case SpcSkip: *start = '\0'; break; case NoSkip: case OffSkip: default: break; } if ('\0' != *start) { pi->pcb->add_text(pi, start, 1); } } pi->s++; pi->pcb->end_element(pi, ename); attr_stack_cleanup(&attrs); return 0; case '\0': attr_stack_cleanup(&attrs); if (TolerantEffort == pi->options->effort) { return 0; } else { set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; } default: first = 0; /* a child element */ // Child closed with mismatched name. if (0 != (name = read_element(pi))) { attr_stack_cleanup(&attrs); if (0 == ((TolerantEffort == pi->options->effort) ? strcasecmp(name, ename) : strcmp(name, ename))) { pi->s++; pi->pcb->end_element(pi, ename); return 0; } else { // not the correct element yet pi->pcb->end_element(pi, ename); return name; } } else if (err_has(&pi->err)) { return 0; } break; } } else { /* read as TEXT */ pi->s = start; /*pi->s--; */ read_text(pi); /*read_reduced_text(pi); */ /* to exit read_text with no errors the next character must be < */ if ('/' == *(pi->s + 1) && 0 == ((TolerantEffort == pi->options->effort) ? strncasecmp(ename, pi->s + 2, elen) : strncmp(ename, pi->s + 2, elen)) && '>' == *(pi->s + elen + 2)) { /* close tag after text so treat as a value */ pi->s += elen + 3; pi->pcb->end_element(pi, ename); attr_stack_cleanup(&attrs); return 0; } } } } attr_stack_cleanup(&attrs); return 0; } static void read_text(PInfo pi) { char buf[MAX_TEXT_LEN]; char *b = buf; char *alloc_buf = 0; char *end = b + sizeof(buf) - 2; char c; int done = 0; while (!done) { c = *pi->s++; switch (c) { case '<': done = 1; pi->s--; break; case '\0': set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return; default: if (end <= (b + (('&' == c) ? 7 : 0))) { /* extra 8 for special just in case it is sequence of bytes */ unsigned long size; if (0 == alloc_buf) { size = sizeof(buf) * 2; alloc_buf = ALLOC_N(char, size); memcpy(alloc_buf, buf, b - buf); b = alloc_buf + (b - buf); } else { unsigned long pos = b - alloc_buf; size = (end - alloc_buf) * 2; REALLOC_N(alloc_buf, char, size); b = alloc_buf + pos; } end = alloc_buf + size - 2; } if ('&' == c) { if (0 == (b = read_coded_chars(pi, b))) { return; } } else { if (0 <= c && c <= 0x20) { if (StrictEffort == pi->options->effort && 'x' == xml_valid_lower_chars[(unsigned char)c]) { set_error(&pi->err, "invalid character", pi->str, pi->s); return; } switch (pi->options->skip) { case CrSkip: if (buf != b && '\n' == c && '\r' == *(b - 1)) { *(b - 1) = '\n'; } else { *b++ = c; } break; case SpcSkip: if (is_white(c)) { if (buf == b || ' ' != *(b - 1)) { *b++ = ' '; } } else { *b++ = c; } break; case NoSkip: case OffSkip: default: *b++ = c; break; } } else { *b++ = c; } } break; } } *b = '\0'; if (0 != alloc_buf) { fix_newlines(alloc_buf); pi->pcb->add_text(pi, alloc_buf, ('/' == *(pi->s + 1))); xfree(alloc_buf); } else { fix_newlines(buf); pi->pcb->add_text(pi, buf, ('/' == *(pi->s + 1))); } } #if 0 static void read_reduced_text(PInfo pi) { char buf[MAX_TEXT_LEN]; char *b = buf; char *alloc_buf = 0; char *end = b + sizeof(buf) - 2; char c; int spc = 0; int done = 0; while (!done) { c = *pi->s++; switch(c) { case ' ': case '\t': case '\f': case '\n': case '\r': spc = 1; break; case '<': done = 1; pi->s--; break; case '\0': set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return; default: if (end <= (b + spc + (('&' == c) ? 7 : 0))) { /* extra 8 for special just in case it is sequence of bytes */ unsigned long size; if (0 == alloc_buf) { size = sizeof(buf) * 2; alloc_buf = ALLOC_N(char, size); memcpy(alloc_buf, buf, b - buf); b = alloc_buf + (b - buf); } else { unsigned long pos = b - alloc_buf; size = (end - alloc_buf) * 2; REALLOC(alloc_buf, char, size); b = alloc_buf + pos; } end = alloc_buf + size - 2; } if (spc) { *b++ = ' '; } spc = 0; if ('&' == c) { if (0 == (b = read_coded_chars(pi, b))) { return; } } else { *b++ = c; } break; } } *b = '\0'; if (0 != alloc_buf) { fix_newlines(alloc_buf); pi->pcb->add_text(pi, alloc_buf, ('/' == *(pi->s + 1))); xfree(alloc_buf); } else { fix_newlines(buf); pi->pcb->add_text(pi, buf, ('/' == *(pi->s + 1))); } } #endif static char *read_name_token(PInfo pi) { char *start; next_non_white(pi); start = pi->s; for (; 1; pi->s++) { switch (*pi->s) { case ' ': case '\t': case '\f': case '?': case '=': case '/': case '>': case '\n': case '\r': return start; case '\0': /* documents never terminate after a name token */ set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; break; /* to avoid warnings */ case ':': if ('\0' == *pi->options->strip_ns) { break; } else if ('*' == *pi->options->strip_ns && '\0' == pi->options->strip_ns[1]) { start = pi->s + 1; } else if (0 == strncmp(pi->options->strip_ns, start, pi->s - start)) { start = pi->s + 1; } break; default: break; } } return start; } static void read_cdata(PInfo pi) { char *start; char *end; start = pi->s; end = strstr(pi->s, "]]>"); if (end == 0) { set_error(&pi->err, "invalid format, CDATA not terminated", pi->str, pi->s); return; } *end = '\0'; pi->s = end + 3; if (0 != pi->pcb->add_cdata) { fix_newlines(start); pi->pcb->add_cdata(pi, start, end - start); } } /* Assume the value starts immediately and goes until the quote character is * reached again. Do not read the character after the terminating quote. */ static char *read_quoted_value(PInfo pi) { char *value = 0; if ('"' == *pi->s || '\'' == *pi->s) { char term = *pi->s; pi->s++; /* skip quote character */ value = pi->s; for (; *pi->s != term; pi->s++) { if ('\0' == *pi->s) { set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; } } *pi->s = '\0'; /* terminate value */ pi->s++; /* move past quote */ } else if (StrictEffort == pi->options->effort) { set_error(&pi->err, "invalid format, expected a quote character", pi->str, pi->s); return 0; } else if (TolerantEffort == pi->options->effort) { value = pi->s; for (; 1; pi->s++) { switch (*pi->s) { case '\0': set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; case ' ': case '/': case '>': case '?': // for instructions case '\t': case '\n': case '\r': pi->last = *pi->s; *pi->s = '\0'; /* terminate value */ pi->s++; return value; default: break; } } } else { value = pi->s; next_white(pi); if ('\0' == *pi->s) { set_error(&pi->err, "invalid format, document not terminated", pi->str, pi->s); return 0; } *pi->s++ = '\0'; /* terminate value */ } return value; } static char *read_hex_uint64(char *b, uint64_t *up) { uint64_t u = 0; char c; for (; ';' != *b; b++) { c = *b; if ('0' <= c && c <= '9') { u = (u << 4) | (uint64_t)(c - '0'); } else if ('a' <= c && c <= 'f') { u = (u << 4) | (uint64_t)(c - 'a' + 10); } else if ('A' <= c && c <= 'F') { u = (u << 4) | (uint64_t)(c - 'A' + 10); } else { return 0; } } *up = u; return b; } static char *read_10_uint64(char *b, uint64_t *up) { uint64_t u = 0; char c; for (; ';' != *b; b++) { c = *b; if ('0' <= c && c <= '9') { u = (u * 10) + (uint64_t)(c - '0'); } else { return 0; } } *up = u; return b; } static char *read_coded_chars(PInfo pi, char *text) { char *b, buf[32]; char *end = buf + sizeof(buf) - 1; char *s; long blen = 0; for (b = buf, s = pi->s; b < end; b++, s++) { *b = *s; if (';' == *s) { *(b + 1) = '\0'; blen = b - buf; s++; break; } } if (b > end) { *text++ = '&'; } else if ('#' == *buf) { uint64_t u = 0; b = buf + 1; if ('x' == *b || 'X' == *b) { b = read_hex_uint64(b + 1, &u); } else { b = read_10_uint64(b, &u); } if (0 == b) { *text++ = '&'; } else { if (u <= 0x000000000000007FULL) { *text++ = (char)u; } else if (ox_utf8_encoding == pi->options->rb_enc) { text = ox_ucs_to_utf8_chars(text, u); } else if (0 == pi->options->rb_enc) { pi->options->rb_enc = ox_utf8_encoding; text = ox_ucs_to_utf8_chars(text, u); } else if (TolerantEffort == pi->options->effort) { *text++ = '&'; return text; } else if (u <= 0x00000000000000FFULL) { *text++ = (char)u; } else { /*set_error(&pi->err, "Invalid encoding, need UTF-8 or UTF-16 encoding to parse &#nnnn; character * sequences.", pi->str, pi->s); */ set_error(&pi->err, "Invalid encoding, need UTF-8 encoding to parse &#nnnn; character sequences.", pi->str, pi->s); return NULL; } pi->s = s; } } else { char *t2; buf[blen] = '\0'; if (NULL == (t2 = ox_entity_lookup(text, buf))) { *text++ = '&'; } else { text = t2; pi->s = s; } } return text; } static int collapse_special(PInfo pi, char *str) { char *s = str; char *b = str; while ('\0' != *s) { if ('&' == *s) { int c; char *end; s++; if ('#' == *s) { uint64_t u = 0; char x; s++; if ('x' == *s || 'X' == *s) { x = *s; s++; end = read_hex_uint64(s, &u); } else { x = '\0'; end = read_10_uint64(s, &u); } if (0 == end) { if (TolerantEffort == pi->options->effort) { *b++ = '&'; *b++ = '#'; if ('\0' != x) { *b++ = x; } continue; } return EDOM; } if (u <= 0x000000000000007FULL) { *b++ = (char)u; } else if (ox_utf8_encoding == pi->options->rb_enc) { b = ox_ucs_to_utf8_chars(b, u); /* TBD support UTF-16 */ } else if (0 == pi->options->rb_enc) { pi->options->rb_enc = ox_utf8_encoding; b = ox_ucs_to_utf8_chars(b, u); } else { /* set_error(&pi->err, "Invalid encoding, need UTF-8 or UTF-16 encoding to parse &#nnnn; character * sequences.", pi->str, pi->s);*/ set_error(&pi->err, "Invalid encoding, need UTF-8 encoding to parse &#nnnn; character sequences.", pi->str, pi->s); return 0; } s = end + 1; } else { if (0 == strncasecmp(s, "lt;", 3)) { c = '<'; s += 3; } else if (0 == strncasecmp(s, "gt;", 3)) { c = '>'; s += 3; } else if (0 == strncasecmp(s, "amp;", 4)) { c = '&'; s += 4; } else if (0 == strncasecmp(s, "quot;", 5)) { c = '"'; s += 5; } else if (0 == strncasecmp(s, "apos;", 5)) { c = '\''; s += 5; } else if (TolerantEffort == pi->options->effort) { *b++ = '&'; continue; } else { char key[16]; char *k = key; char *kend = key + sizeof(key) - 1; *k++ = *s; while (';' != *s++) { if ('\0' == *s) { set_error(&pi->err, "Invalid format, special character does not end with a semicolon", pi->str, pi->s); return EDOM; } if (kend <= k) { k = key; break; } *k++ = *s; } k--; *k = '\0'; if ('\0' == *key || NULL == (b = ox_entity_lookup(b, key))) { set_error(&pi->err, "Invalid format, invalid special character sequence", pi->str, pi->s); c = '?'; return 0; } continue; } *b++ = (char)c; } } else { *b++ = *s++; } } *b = '\0'; return 0; } ox-2.14.17/ext/ox/sax.c000066400000000000000000001413641445411231300145100ustar00rootroot00000000000000/* sax.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include #include #include #include #include #include #if HAVE_SYS_UIO_H #include #endif #include #include #include "intern.h" #include "ox.h" #include "ruby.h" #include "ruby/encoding.h" #include "sax.h" #include "sax_buf.h" #include "sax_stack.h" #include "special.h" #define NAME_MISMATCH 1 #define START_STATE 1 #define BODY_STATE 2 #define AFTER_STATE 3 // error prefixes #define BAD_BOM "Bad BOM: " #define NO_TERM "Not Terminated: " #define INVALID_FORMAT "Invalid Format: " #define CASE_ERROR "Case Error: " #define OUT_OF_ORDER "Out of Order: " #define WRONG_CHAR "Unexpected Character: " #define EL_MISMATCH "Start End Mismatch: " #define INV_ELEMENT "Invalid Element: " #define UTF8_STR "UTF-8" static void sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions options); static void parse(SaxDrive dr); // All read functions should return the next character after the 'thing' that was read and leave dr->cur one after that. static char read_instruction(SaxDrive dr); static char read_doctype(SaxDrive dr); static char read_cdata(SaxDrive dr); static char read_comment(SaxDrive dr); static char read_element_start(SaxDrive dr); static char read_element_end(SaxDrive dr); static char read_text(SaxDrive dr); static char read_jump(SaxDrive dr, const char *pat); static char read_attrs(SaxDrive dr, char c, char termc, char term2, int is_xml, int eq_req, Hint h); static char read_name_token(SaxDrive dr); static char read_quoted_value(SaxDrive dr, bool inst); static void hint_clear_empty(SaxDrive dr); static Nv hint_try_close(SaxDrive dr, const char *name); VALUE ox_sax_value_class = Qnil; static VALUE protect_parse(VALUE drp) { parse((SaxDrive)drp); return Qnil; } VALUE str2sym(SaxDrive dr, const char *str, size_t len, const char **strp) { VALUE sym; if (dr->options.symbolize) { sym = ox_sym_intern(str, len, strp); } else { sym = dr->get_name(str, len, dr->encoding, strp); } return sym; } void ox_sax_parse(VALUE handler, VALUE io, SaxOptions options) { #if HAVE_RB_EXT_RACTOR_SAFE rb_ext_ractor_safe(true); #endif struct _saxDrive dr; int line = 0; sax_drive_init(&dr, handler, io, options); rb_protect(protect_parse, (VALUE)&dr, &line); ox_sax_drive_cleanup(&dr); if (0 != line) { rb_jump_tag(line); } } static void set_long_noop(VALUE handler, long pos) { } static void set_pos(VALUE handler, long pos) { rb_ivar_set(handler, ox_at_pos_id, LONG2NUM(pos)); } static void set_line(VALUE handler, long line) { rb_ivar_set(handler, ox_at_line_id, LONG2NUM(line)); } static void set_col(VALUE handler, long col) { rb_ivar_set(handler, ox_at_column_id, LONG2NUM(col)); } static void attr_noop(SaxDrive dr, VALUE name, char *value, long pos, long line, long col) { } static void attr_text(SaxDrive dr, VALUE name, char *value, long pos, long line, long col) { VALUE args[2]; args[0] = name; if (dr->options.convert_special && '\0' != value[0]) { ox_sax_collapse_special(dr, value, pos, line, col); } args[1] = rb_str_new2(value); if (0 != dr->encoding) { rb_enc_associate(args[1], dr->encoding); } dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall2(dr->handler, ox_attr_id, 2, args); } static void attr_value(SaxDrive dr, VALUE name, char *value, long pos, long line, long col) { VALUE args[2]; dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); args[0] = name; args[1] = dr->value_obj; rb_funcall2(dr->handler, ox_attr_value_id, 2, args); } static void attrs_done_noop(VALUE handler) { } static void attrs_done(VALUE handler) { rb_funcall(handler, ox_attrs_done_id, 0); } static VALUE instruct_noop(SaxDrive dr, const char *target, long pos, long line, long col) { return Qnil; } static VALUE instruct(SaxDrive dr, const char *target, long pos, long line, long col) { VALUE arg = rb_str_new2(target); dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_instruct_id, 1, arg); return arg; } static VALUE instruct_just_value(SaxDrive dr, const char *target, long pos, long line, long col) { return rb_str_new2(target); } static void end_instruct_noop(SaxDrive dr, VALUE target, long pos, long line, long col) { } static void end_instruct(SaxDrive dr, VALUE target, long pos, long line, long col) { dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_end_instruct_id, 1, target); } static void dr_loc_noop(SaxDrive dr, long pos, long line, long col) { } static void comment(SaxDrive dr, long pos, long line, long col) { if (!dr->blocked) { Nv parent = stack_peek(&dr->stack); Hint h = ox_hint_find(dr->options.hints, "!--"); if (NULL == parent || NULL == parent->hint || OffOverlay != parent->hint->overlay || (NULL != h && (ActiveOverlay == h->overlay || ActiveOverlay == h->overlay))) { VALUE arg = rb_str_new2(dr->buf.str); if (0 != dr->encoding) { rb_enc_associate(arg, dr->encoding); } dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_comment_id, 1, arg); } } } static void cdata(SaxDrive dr, long pos, long line, long col) { Nv parent = stack_peek(&dr->stack); if (!dr->blocked && (NULL == parent || NULL == parent->hint || OffOverlay != parent->hint->overlay)) { VALUE arg = rb_str_new2(dr->buf.str); if (0 != dr->encoding) { rb_enc_associate(arg, dr->encoding); } dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_cdata_id, 1, arg); } } static void doctype(SaxDrive dr, long pos, long line, long col) { dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_doctype_id, 1, rb_str_new2(dr->buf.str)); } static void error_noop(SaxDrive dr, const char *msg, long pos, long line, long col) { } static void error(SaxDrive dr, const char *msg, long pos, long line, long col) { VALUE args[3]; args[0] = rb_str_new2(msg); args[1] = LONG2NUM(line); args[2] = LONG2NUM(col); dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall2(dr->handler, ox_error_id, 3, args); } static void end_element_cb(SaxDrive dr, VALUE name, long pos, long line, long col, Hint h) { if (dr->has_end_element && 0 >= dr->blocked && (NULL == h || ActiveOverlay == h->overlay || NestOverlay == h->overlay)) { dr->set_pos(dr->handler, pos); dr->set_line(dr->handler, line); dr->set_col(dr->handler, col); rb_funcall(dr->handler, ox_end_element_id, 1, name); } if (NULL != h && BlockOverlay == h->overlay && 0 < dr->blocked) { dr->blocked--; } } static void sax_drive_init(SaxDrive dr, VALUE handler, VALUE io, SaxOptions options) { ox_sax_buf_init(&dr->buf, io); dr->buf.dr = dr; stack_init(&dr->stack); dr->handler = handler; dr->value_obj = Data_Wrap_Struct(ox_sax_value_class, 0, 0, dr); rb_gc_register_address(&dr->value_obj); dr->options = *options; dr->err = 0; dr->blocked = 0; dr->abort = false; dr->set_pos = (Qtrue == rb_ivar_defined(handler, ox_at_pos_id)) ? set_pos : set_long_noop; dr->set_line = (Qtrue == rb_ivar_defined(handler, ox_at_line_id)) ? set_line : set_long_noop; dr->set_col = (Qtrue == rb_ivar_defined(handler, ox_at_column_id)) ? set_col : set_long_noop; if (rb_respond_to(handler, ox_attr_value_id)) { dr->attr_cb = attr_value; dr->want_attr_name = true; } else if (rb_respond_to(handler, ox_attr_id)) { dr->attr_cb = attr_text; dr->want_attr_name = true; } else { dr->attr_cb = attr_noop; dr->want_attr_name = false; } dr->attrs_done = rb_respond_to(handler, ox_attrs_done_id) ? attrs_done : attrs_done_noop; dr->instruct = rb_respond_to(handler, ox_instruct_id) ? instruct : instruct_noop; dr->end_instruct = rb_respond_to(handler, ox_end_instruct_id) ? end_instruct : end_instruct_noop; if (rb_respond_to(handler, ox_end_instruct_id) && !rb_respond_to(handler, ox_instruct_id)) { dr->instruct = instruct_just_value; } dr->doctype = rb_respond_to(handler, ox_doctype_id) ? doctype : dr_loc_noop; dr->comment = rb_respond_to(handler, ox_comment_id) ? comment : dr_loc_noop; dr->cdata = rb_respond_to(handler, ox_cdata_id) ? cdata : dr_loc_noop; dr->error = rb_respond_to(handler, ox_error_id) ? error : error_noop; dr->has_text = rb_respond_to(handler, ox_text_id); dr->has_value = rb_respond_to(handler, ox_value_id); dr->has_start_element = rb_respond_to(handler, ox_start_element_id); dr->has_end_element = rb_respond_to(handler, ox_end_element_id); if ('\0' == *ox_default_options.encoding) { VALUE encoding; dr->encoding = 0; if (rb_respond_to(io, ox_external_encoding_id) && Qnil != (encoding = rb_funcall(io, ox_external_encoding_id, 0))) { int e = rb_enc_get_index(encoding); if (0 <= e) { dr->encoding = rb_enc_from_index(e); } } } else { dr->encoding = rb_enc_find(ox_default_options.encoding); } dr->utf8 = (NULL == dr->encoding || rb_utf8_encoding() == dr->encoding); if (NULL == dr->encoding || rb_utf8_encoding() == dr->encoding) { // UTF-8 dr->get_name = dr->options.symbolize ? ox_utf8_sym : ox_utf8_name; // TBD UTF8 sym? } else { dr->get_name = dr->options.symbolize ? ox_enc_sym : ox_enc_name; } } void ox_sax_drive_cleanup(SaxDrive dr) { rb_gc_unregister_address(&dr->value_obj); buf_cleanup(&dr->buf); stack_cleanup(&dr->stack); } static void ox_sax_drive_error_at(SaxDrive dr, const char *msg, off_t pos, off_t line, off_t col) { dr->error(dr, msg, pos, line, col); } void ox_sax_drive_error(SaxDrive dr, const char *msg) { ox_sax_drive_error_at(dr, msg, dr->buf.pos, dr->buf.line, dr->buf.col); } static char skipBOM(SaxDrive dr) { char c = buf_get(&dr->buf); if (0xEF == (uint8_t)c) { /* only UTF8 is supported */ if (0xBB == (uint8_t)buf_get(&dr->buf) && 0xBF == (uint8_t)buf_get(&dr->buf)) { dr->encoding = ox_utf8_encoding; c = buf_get(&dr->buf); } else { ox_sax_drive_error(dr, BAD_BOM "invalid BOM or a binary file."); c = '\0'; } } return c; } static void parse(SaxDrive dr) { char c = skipBOM(dr); int state = START_STATE; Nv parent; while ('\0' != c) { buf_protect(&dr->buf); if ('<' == c) { c = buf_get(&dr->buf); switch (c) { case '?': /* instructions (xml or otherwise) */ c = read_instruction(dr); break; case '!': /* comment or doctype */ buf_protect(&dr->buf); c = buf_get(&dr->buf); if ('\0' == c) { ox_sax_drive_error(dr, NO_TERM "DOCTYPE or comment not terminated"); goto DONE; } else if ('-' == c) { c = buf_get(&dr->buf); /* skip first - and get next character */ if ('-' != c) { ox_sax_drive_error(dr, INVALID_FORMAT "bad comment format, expected {"ucirc", 251}, // latin small letter u with circumflex {"ugrave", 249}, // latin small letter u with grave {"uml", 168}, // diaeresis = spacing diaeresis {"upsih", 978}, // greek upsilon with hook symbol {"upsilon", 965}, // greek small letter upsilon {"uuml", 252}, // latin small letter u with diaeresis {"weierp", 8472}, // script capital P = power set {"xi", 958}, // greek small letter xi, U+03BE ISOgrk3 {"yacute", 253}, // latin small letter y with acute {"yen", 165}, // yen sign = yuan sign, U+00A5 ISOnum {"yuml", 255}, // latin small letter y with diaeresis {"zeta", 950}, // greek small letter zeta, U+03B6 ISOgrk3 {"zwj", 8205}, // zero width joiner, U+200D NEW RFC 2070 {"zwnj", 8204}, // zero width non-joiner {NULL, 0}, }; static uint64_t calc_hash(const char *key) { uint64_t h = 0; if (NULL != key) { const uint8_t *k = (const uint8_t *)key; for (; 0 != *k; k++) { // narrow to most used range of 0x4D (77) in size h = 77 * h + ((*k | 0x20) - 0x2D); } } return h; } static Slot *get_bucketp(uint64_t h) { return entity_cache.buckets + (BUCKET_MASK & (h ^ (h << 5) ^ (h >> 7))); } static void cache_set(Slot s) { int64_t h = calc_hash(s->key); Slot *bucket = get_bucketp(h); s->hash = h; s->next = *bucket; *bucket = s; } static Slot cache_get(const char *key) { int64_t h = calc_hash(key); Slot *bucket = get_bucketp(h); Slot s; for (s = *bucket; NULL != s; s = s->next) { if (h == (int64_t)s->hash && 0 == strcasecmp(s->key, key)) { return s; } } return NULL; } static void cache_init() { Slot e = entities; memset(&entity_cache, 0, sizeof(struct _cache)); for (; NULL != e->key; e++) { cache_set(e); } inited = true; } char *ox_entity_lookup(char *text, const char *key) { Slot s = entities; if (!inited) { cache_init(); } if (NULL == (s = cache_get(key))) { return NULL; } return ox_ucs_to_utf8_chars(text, s->code); } ox-2.14.17/ext/ox/special.h000066400000000000000000000004371445411231300153350ustar00rootroot00000000000000/* special.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_SPECIAL_H #define OX_SPECIAL_H #include extern char *ox_ucs_to_utf8_chars(char *text, uint64_t u); extern char *ox_entity_lookup(char *text, const char *key); #endif /* OX_SPECIAL_H */ ox-2.14.17/ext/ox/type.h000066400000000000000000000017121445411231300146730ustar00rootroot00000000000000/* type.h * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #ifndef OX_TYPE_H #define OX_TYPE_H typedef enum { NoCode = 0, ArrayCode = 'a', String64Code = 'b', /* base64 encoded String */ ClassCode = 'c', Symbol64Code = 'd', /* base64 encoded Symbol */ DateCode = 'D', BigDecimalCode = 'B', ExceptionCode = 'e', FloatCode = 'f', RegexpCode = 'g', HashCode = 'h', FixnumCode = 'i', BignumCode = 'j', KeyCode = 'k', /* indicates the value is a hash key, kind of a hack */ RationalCode = 'l', SymbolCode = 'm', FalseClassCode = 'n', ObjectCode = 'o', RefCode = 'p', RangeCode = 'r', StringCode = 's', TimeCode = 't', StructCode = 'u', ComplexCode = 'v', RawCode = 'x', TrueClassCode = 'y', NilClassCode = 'z', } Type; #endif /* OX_TYPE_H */ ox-2.14.17/lib/000077500000000000000000000000001445411231300130605ustar00rootroot00000000000000ox-2.14.17/lib/ox.rb000066400000000000000000000034311445411231300140340ustar00rootroot00000000000000# Copyright (c) 2011, Peter Ohler
# All rights reserved. # # === Description: # # Ox handles XML documents in two ways. It is a generic XML parser and writer as # well as a fast Object / XML marshaller. Ox was written for speed as a # replacement for Nokogiri and for Marshal. # # As an XML parser it is 2 or more times faster than Nokogiri and as a generic # XML writer it is 14 times faster than Nokogiri. Of course different files may # result in slightly different times. # # As an Object serializer Ox is 4 times faster than the standard Ruby # Marshal.dump(). Ox is 3 times faster than Marshal.load(). # # === Object Dump Sample: # # require 'ox' # # class Sample # attr_accessor :a, :b, :c # # def initialize(a, b, c) # @a = a # @b = b # @c = c # end # end # # # Create Object # obj = Sample.new(1, "bee", ['x', :y, 7.0]) # # Now dump the Object to an XML String. # xml = Ox.dump(obj) # # Convert the object back into a Sample Object. # obj2 = Ox.parse_obj(xml) # # === Generic XML Writing and Parsing: # # require 'ox' # # doc = Ox::Document.new(:version => '1.0') # # top = Ox::Element.new('top') # top[:name] = 'sample' # doc << top # # mid = Ox::Element.new('middle') # mid[:name] = 'second' # top << mid # # bot = Ox::Element.new('bottom') # bot[:name] = 'third' # mid << bot # # xml = Ox.dump(doc) # puts xml # doc2 = Ox.parse(xml) # puts "Same? #{doc == doc2}" module Ox end require 'ox/version' require 'ox/error' require 'ox/hasattrs' require 'ox/node' require 'ox/comment' require 'ox/raw' require 'ox/instruct' require 'ox/cdata' require 'ox/doctype' require 'ox/element' require 'ox/document' require 'ox/bag' require 'ox/sax' # C extension begin require_relative 'ox.so' rescue LoadError require 'ox/ox' end ox-2.14.17/lib/ox/000077500000000000000000000000001445411231300135065ustar00rootroot00000000000000ox-2.14.17/lib/ox/bag.rb000066400000000000000000000067521445411231300145760ustar00rootroot00000000000000module Ox # A generic class that is used only for storing attributes. It is the base # Class for auto-generated classes in the storage system. Instance variables # are added using the instance_variable_set() method. All instance variables # can be accessed using the variable name (without the @ prefix). No setters # are provided as the Class is intended for reading only. class Bag # The initializer can take multiple arguments in the form of key values # where the key is the variable name and the value is the variable # value. This is intended for testing purposes only. # - +args+ [Hash] instance variable symbols and their values # # *Example* # # Ox::Bag.new(:@x => 42, :@y => 57) # def initialize(args={}) args.each do |k, v| instance_variable_set(k, v) end end # Replaces the Object.respond_to?() method. # - +m+ [Symbol] method symbol # *return* [Boolean] true for any method that matches an instance variable # reader, otherwise false. def respond_to?(m) return true if super at_m = ('@' + m.to_s).to_sym instance_variables.include?(at_m) end # Handles requests for variable values. Others cause an Exception to be # raised. # - +m+ (Symbol) method symbol # *return* [Boolean] the value of the specified instance variable. # # _raise_ [ArgumentError] if an argument is given. Zero arguments expected. # # _raise_ [NoMethodError] if the instance variable is not defined. def method_missing(m, *args, &block) unless args.nil? or args.empty? raise ArgumentError.new("wrong number of arguments (#{args.size} for 0) to method #{m}") end at_m = ('@' + m.to_s).to_sym raise NoMethodError.new("undefined method #{m}", m) unless instance_variable_defined?(at_m) instance_variable_get(at_m) end # Replaces eql?() with something more reasonable for this Class. # - +other+ [Object] Object to compare self to # *return* [Boolean] true if each variable and value are the same, otherwise false. def eql?(other) return false if (other.nil? or self.class != other.class) ova = other.instance_variables iv = instance_variables return false if ova.size != iv.size iv.each do |vid| return false if instance_variable_get(vid) != other.instance_variable_get(vid) end true end alias == eql? # Define a new class based on the Ox::Bag class. This is used internally in # the Ox module and is available to service wrappers that receive XML # requests that include Objects of Classes not defined in the storage # process. # - +classname+ (String) Class name or symbol that includes Module names. # *return* [Object] an instance of the specified Class. # # _raise_ [NameError] if the classname is invalid. def self.define_class(classname) classname = classname.to_s unless classname.is_a?(String) tokens = classname.split('::').map { |n| n.to_sym } raise NameError.new("Invalid classname '#{classname}") if tokens.empty? m = Object tokens[0..-2].each do |sym| if m.const_defined?(sym) m = m.const_get(sym) else c = Module.new m.const_set(sym, c) m = c end end sym = tokens[-1] if m.const_defined?(sym) c = m.const_get(sym) else c = Class.new(Ox::Bag) m.const_set(sym, c) end c end end # Bag end # Ox ox-2.14.17/lib/ox/cdata.rb000066400000000000000000000003621445411231300151100ustar00rootroot00000000000000module Ox # CData represents a CDATA element in an XML document. class CData < Node # Creates a CDATA element. # - +value+ [String] value for the CDATA contents def initialize(value) super end end # CData end # Ox ox-2.14.17/lib/ox/comment.rb000066400000000000000000000004661445411231300155030ustar00rootroot00000000000000module Ox # Comments represent XML comments in an XML document. A comment has a value # attribute only. class Comment < Node # Creates a new Comment with the specified value. # - +value+ [String] string value for the comment def initialize(value) super end end # Comment end # Ox ox-2.14.17/lib/ox/doctype.rb000066400000000000000000000004611445411231300155030ustar00rootroot00000000000000module Ox # Represents a DOCTYPE in an XML document. class DocType < Node # Creates a DOCTYPE elements with the content as a string specified in the # value parameter. # - +value+ [String] string value for the element def initialize(value) super end end # DocType end # Ox ox-2.14.17/lib/ox/document.rb000066400000000000000000000020211445411231300156440ustar00rootroot00000000000000module Ox # Represents an XML document. It has a fixed set of attributes which form # the XML prolog. A Document includes Elements. class Document < Element # Create a new Document. # - +prolog+ [Hash] prolog attributes # - _:version_ [String] version, typically '1.0' or '1.1' # - _:encoding_ [String] encoding for the document, currently included but ignored # - _:standalone_ [String] indicates the document is standalone def initialize(prolog={}) super(nil) @attributes = {} @attributes[:version] = prolog[:version] unless prolog[:version].nil? @attributes[:encoding] = prolog[:encoding] unless prolog[:encoding].nil? @attributes[:standalone] = prolog[:standalone] unless prolog[:standalone].nil? end # Returns the first Element in the document. def root unless !instance_variable_defined?(:@nodes) || @nodes.nil? @nodes.each do |n| return n if n.is_a?(::Ox::Element) end end nil end end # Document end # Ox ox-2.14.17/lib/ox/element.rb000066400000000000000000000415751445411231300155000ustar00rootroot00000000000000module Ox # An Element represents a element of an XML document. It has a name, # attributes, and sub-nodes. # # To access the child elements or attributes there are several options. One # is to walk the nodes and attributes. Another is to use the locate() # method. The easiest for simple regularly formatted XML is to reference the # sub elements or attributes simply by name. Repeating elements with the # same name can be referenced with an element count as well. A few examples # should explain the 'easy' API more clearly. # # *Example* # # doc = Ox.parse(%{ # # # # Peter # Ohler # # # Makie # Ohler # # # }) # # doc.People.Person.given.text # => "Peter" # doc.People.Person(1).given.text # => "Makie" # doc.People.Person.age # => "58" class Element < Node include HasAttrs # Creates a new Element with the specified name. # - +name+ [String] name of the Element def initialize(name) super @attributes = {} @nodes = [] end alias name value alias name= value= # Returns the Element's nodes array. These are the sub-elements of this # Element. # *return* [Array] all child Nodes. def nodes @nodes = [] if !instance_variable_defined?(:@nodes) or @nodes.nil? @nodes end # Appends a Node to the Element's nodes array. Returns the element itself # so multiple appends can be chained together. # - +node+ [Node] Node to append to the nodes array def <<(node) raise 'argument to << must be a String or Ox::Node.' unless node.is_a?(String) or node.is_a?(Node) @nodes = [] if !instance_variable_defined?(:@nodes) or @nodes.nil? @nodes << node self end # Prepend a Node to the Element's nodes array. Returns the element itself # so multiple appends can be chained together. # - +node+ [Node] Node to prepend to the nodes array def prepend_child(node) raise 'argument to << must be a String or Ox::Node.' unless node.is_a?(String) or node.is_a?(Node) @nodes = [] if !instance_variable_defined?(:@nodes) or @nodes.nil? @nodes.unshift(node) self end # Returns true if this Object and other are of the same type and have the # equivalent value and the equivalent elements otherwise false is returned. # - +other+ [Object] Object compare _self_ to. # *return* [Boolean] true if both Objects are equivalent, otherwise false. def eql?(other) return false unless super(other) return false unless attributes == other.attributes return false unless nodes == other.nodes true end alias == eql? # Returns the first String in the elements nodes array or nil if there is # no String node. def text nodes.each { |n| return n if n.is_a?(String) } nil end # Clears any child nodes of an element and replaces those with a single Text # (String) node. Note the existing nodes array is modified and not replaced. # - +txt+ [String] to become the only element of the nodes array def replace_text(txt) raise 'the argument to replace_text() must be a String' unless txt.is_a?(String) @nodes.clear @nodes << txt end # Return true if all the key-value pairs in the cond Hash match the # @attributes key-values. def attr_match(cond) cond.each_pair { |k, v| return false unless v == @attributes[k.to_sym] || v == @attributes[k.to_s] } true end # Iterate over each child of the instance yielding according to the cond # argument value. If the cond argument is nil then all child nodes are # yielded to. If cond is a string then only the child Elements with a # matching name will be yielded to. If the cond is a Hash then the # keys-value pairs in the cond must match the child attribute values with # the same keys. Any other cond type will yield to nothing. def each(cond=nil, &block) build_enumerator(cond).each(&block) end # Returns an array of Nodes or Strings that correspond to the locations # specified by the path parameter. The path parameter describes the path # to the return values which can be either nodes in the XML or # attributes. The path is a relative description. There are similarities # between the locate() method and XPath but locate does not follow the # same rules as XPath. The syntax is meant to be simpler and more Ruby # like. # # Like XPath the path delimiters are the slash (/) character. The path is # split on the delimiter and each element of the path then describes the # child of the current Element to traverse. # # Attributes are specified with an @ prefix. # # Each element name in the path can be followed by a bracket expression # that narrows the paths to traverse. Supported expressions are numbers # with a preceeding qualifier. Qualifiers are -, +, <, and >. The + # qualifier is the default. A - qualifier indicates the index begins at # the end of the children just like for Ruby Arrays. The < and > # qualifiers indicates all elements either less than or greater than # should be matched. Note that unlike XPath, the element index starts at 0 # similar to Ruby be contrary to XPath. # # Element names can also be wildcard characters. A * indicates any decendent should be followed. A ? indicates any # single Element can match the wildcard. A ^ character followed by the name of a Class will match any node of the # specified class. Valid class names are Element, Comment, String (or Text), CData, DocType. # # Examples are: # * element.locate("Family/Pete/*") returns all children of the Pete Element. # * element.locate("Family/?[1]") returns the first element in the Family Element. # * element.locate("Family/?[<3]") returns the first 3 elements in the Family Element. # * element.locate("Family/?[@age]") returns the elements with an age attribute defined in the Family Element. # * element.locate("Family/Kid[@age]") returns the Kid elements with an age attribute defined in the Family Element. # * element.locate("Family/?[@age=32]") returns the elements with an age attribute equal to 32 in the Family Element. # * element.locate("Family/Kid[@age=32]") returns the Kid elements with an age attribute equal to 32 in the Family Element. # * element.locate("Family/?/@age") returns the arg attribute for each child in the Family Element. # * element.locate("Family/*/@type") returns the type attribute value for decendents of the Family. # * element.locate("Family/^Comment") returns any comments that are a child of Family. # # - +path+ [String] path to the Nodes to locate def locate(path) return [self] if path.nil? found = [] pa = path.split('/') if '*' == path[0] # a bit of a hack but it allows self to be checked as well e = Element.new('') e << self e.alocate(pa, found) else alocate(pa, found) end found end # Remove all the children matching the path provided # # Examples are: # * element.remove_children(Ox:Element) removes the element passed as argument if child of the element. # * element.remove_children(Ox:Element, Ox:Element) removes the list of elements passed as argument if children of the element. # # - +children+ [Array] array of OX def remove_children(*children) return self if children.compact.empty? recursive_children_removal(children.compact.map { |c| c.object_id }) self end # Remove all the children matching the path provided # # Examples are: # * element.remove_children_by_path("*") removes all children attributes. # * element.remove_children_by_path("Family/Kid[@age=32]") removes the Kid elements with an age attribute equal to 32 in the Family Element. # # - +path+ [String] path to the Nodes to locate def remove_children_by_path(path) del_locate(path.split('/')) unless path.nil? self end # Handles the 'easy' API that allows navigating a simple XML by # referencing elements and attributes by name. # - +id+ [Symbol] element or attribute name # *return* [Element|Node|String|nil] the element, attribute value, or Node identifed by the name # # _raise_ [NoMethodError] if no match is found def method_missing(id, *args, &block) has_some = false ids = id.to_s i = args[0].to_i # will be 0 if no arg or parsing fails nodes.each do |n| unless (n.is_a?(Element) || n.is_a?(Instruct)) && (n.value == id || n.value == ids || name_matchs?(n.value, ids)) next end return n if 0 == i has_some = true i -= 1 end if instance_variable_defined?(:@attributes) return @attributes[id] if @attributes.has_key?(id) return @attributes[ids] if @attributes.has_key?(ids) end return nil if has_some raise NoMethodError.new("#{ids} not found", name) end # - +id+ [String|Symbol] identifer of the attribute or method # - +ignored+ inc_all [Boolean] # *return* true if the element has a member that matches the provided name. def respond_to?(id, inc_all=false) return true if super id_str = id.to_s id_sym = id.to_sym nodes.each do |n| next if n.is_a?(String) return true if n.value == id_str || n.value == id_sym || name_matchs?(n.value, id_str) end if instance_variable_defined?(:@attributes) && !@attributes.nil? return true if @attributes.has_key?(id_str) return true if @attributes.has_key?(id_sym) end false end # - +path+ [Array] array of steps in a path # - +found+ [Array] matching nodes def alocate(path, found) step = path[0] if step.start_with?('@') # attribute raise InvalidPath.new(path) unless 1 == path.size if instance_variable_defined?(:@attributes) step = step[1..-1] sym_step = step.to_sym @attributes.each do |k, v| found << v if ('?' == step or k == step or k == sym_step) end end else # element name if (i = step.index('[')).nil? # just name name = step qual = nil else name = step[0..i-1] raise InvalidPath.new(path) unless step.end_with?(']') i += 1 qual = step[i..i] # step[i] would be better but some rubies (jruby, ree, rbx) take that as a Fixnum. if '0' <= qual and qual <= '9' qual = '+' else i += 1 end index = step[i..-2].to_i end if ['?', '*'].include?(name) match = nodes elsif '^' == name[0..0] # 1.8.7 thinks name[0] is a fixnum case name[1..-1] when 'Element' match = nodes.select { |e| e.is_a?(Element) } when 'String', 'Text' match = nodes.select { |e| e.is_a?(String) } when 'Comment' match = nodes.select { |e| e.is_a?(Comment) } when 'CData' match = nodes.select { |e| e.is_a?(CData) } when 'DocType' match = nodes.select { |e| e.is_a?(DocType) } else # puts "*** no match on #{name}" match = [] end else match = nodes.select { |e| e.is_a?(Element) and name == e.name } end unless qual.nil? or match.empty? case qual when '+' match = index < match.size ? [match[index]] : [] when '-' match = index <= match.size ? [match[-index]] : [] when '<' match = 0 < index ? match[0..index - 1] : [] when '>' match = index <= match.size ? match[index + 1..-1] : [] when '@' k, v = step[i..-2].split('=') if v match = match.select { |n| n.is_a?(Element) && (v == n.attributes[k.to_sym] || v == n.attributes[k]) } else match = match.select { |n| n.is_a?(Element) && (n.attributes[k.to_sym] || n.attributes[k]) } end else raise InvalidPath.new(path) end end if (1 == path.size) match.each { |n| found << n } elsif '*' == name match.each { |n| n.alocate(path, found) if n.is_a?(Element) } match.each { |n| n.alocate(path[1..-1], found) if n.is_a?(Element) } else match.each { |n| n.alocate(path[1..-1], found) if n.is_a?(Element) } end end end # - +path+ [Array] array of steps in a path def del_locate(path) step = path[0] if step.start_with?('@') # attribute raise InvalidPath.new(path) unless 1 == path.size if instance_variable_defined?(:@attributes) step = step[1..-1] sym_step = step.to_sym @attributes.delete_if { |k, v| '?' == step || k.to_sym == sym_step } end else # element name if (i = step.index('[')).nil? # just name name = step qual = nil else name = step[0..i-1] raise InvalidPath.new(path) unless step.end_with?(']') i += 1 qual = step[i..i] # step[i] would be better but some rubies (jruby, ree, rbx) take that as a Fixnum. if '0' <= qual and qual <= '9' qual = '+' else i += 1 end index = step[i..-2].to_i end if ['?', '*'].include?(name) match = nodes elsif '^' == name[0..0] # 1.8.7 thinks name[0] is a fixnum case name[1..-1] when 'Element' match = nodes.select { |e| e.is_a?(Element) } when 'String', 'Text' match = nodes.select { |e| e.is_a?(String) } when 'Comment' match = nodes.select { |e| e.is_a?(Comment) } when 'CData' match = nodes.select { |e| e.is_a?(CData) } when 'DocType' match = nodes.select { |e| e.is_a?(DocType) } else # puts "*** no match on #{name}" match = [] end else match = nodes.select { |e| e.is_a?(Element) and name == e.name } end unless qual.nil? or match.empty? case qual when '+' match = index < match.size ? [match[index]] : [] when '-' match = index <= match.size ? [match[-index]] : [] when '<' match = 0 < index ? match[0..index - 1] : [] when '>' match = index <= match.size ? match[index + 1..-1] : [] when '@' k, v = step[i..-2].split('=') if v match = match.select { |n| n.is_a?(Element) && (v == n.attributes[k.to_sym] || v == n.attributes[k]) } else match = match.select { |n| n.is_a?(Element) && (n.attributes[k.to_sym] || n.attributes[k]) } end else raise InvalidPath.new(path) end end if (1 == path.size) nodes.delete_if { |n| match.include?(n) } elsif '*' == name match.each { |n| n.del_locate(path) if n.is_a?(Element) } match.each { |n| n.del_locate(path[1..-1]) if n.is_a?(Element) } else match.each { |n| n.del_locate(path[1..-1]) if n.is_a?(Element) } end end end private # Builds an enumerator for use in `#each` call # # - +cond+ [Hash, String, nil] an element filter def build_enumerator(cond) if cond.nil? nodes.each else cond = cond.to_s if cond.is_a?(Symbol) Enumerator.new do |yielder| if cond.is_a?(String) nodes.each { |n| yielder.yield(n) if n.is_a?(Element) && cond == n.name } elsif cond.is_a?(Hash) nodes.each { |n| yielder.yield(n) if n.is_a?(Element) && n.attr_match(cond) } end end end end # Removes recursively children for nodes and sub_nodes # # - +found+ [Array] An array of Ox::Element def recursive_children_removal(found) return if found.empty? nodes.tap do |ns| # found.delete(n.object_id) stops looking for an already found object_id ns.delete_if { |n| found.include?(n.object_id) ? found.delete(n.object_id) : false } nodes.each do |n| n.send(:recursive_children_removal, found) if n.is_a?(Ox::Element) end end end def name_matchs?(pat, id) return false unless pat.length == id.length pat.length.times { |i| return false unless '_' == id[i] || pat[i] == id[i] } true end end # Element end # Ox ox-2.14.17/lib/ox/error.rb000066400000000000000000000012651445411231300151700ustar00rootroot00000000000000module Ox # Base error class for Ox errors. class Error < StandardError end # Error # An Exception that is raised as a result of a parse error while parsing a XML document. class ParseError < Error end # ParseError # An Exception that is raised as a result of an invalid argument. class ArgError < Error end # ArgError # An Exception that is raised as a result of invalid XML syntax. class SyntaxError < Error end # An Exception raised if a path is not valid. class InvalidPath < Error # Create a new instance with the +path+ specified. def initialize(path) super("#{path.join('/')} is not a valid location.") end end # InvalidPath end # Ox ox-2.14.17/lib/ox/hasattrs.rb000066400000000000000000000041211445411231300156620ustar00rootroot00000000000000module Ox # An Object that includes the HasAttrs module can have attributes which are a Hash of String values and either String # or Symbol keys. # # To access the attributes there are several options. One is to walk the attributes. The easiest for simple regularly # formatted XML is to reference the attributes simply by name. module HasAttrs # Returns all the attributes of the Instruct as a Hash. # *return* [Hash] all attributes and attribute values. def attributes @attributes = {} if !instance_variable_defined?(:@attributes) or @attributes.nil? @attributes end # Returns the value of an attribute. # - +attr+ [Symbol|String] attribute name or key to return the value for def [](attr) return nil unless instance_variable_defined?(:@attributes) and @attributes.is_a?(Hash) @attributes[attr] or (attr.is_a?(String) ? @attributes[attr.to_sym] : @attributes[attr.to_s]) end # Adds or set an attribute of the Instruct. # - +attr+ [Symbol|String] attribute name or key # - +value+ [Object] value for the attribute def []=(attr, value) raise 'argument to [] must be a Symbol or a String.' unless attr.is_a?(Symbol) or attr.is_a?(String) @attributes = {} if !instance_variable_defined?(:@attributes) or @attributes.nil? a_str = attr.to_s a_sym = attr.to_sym if @attributes.has_key?(a_str) attr = a_str elsif @attributes.has_key?(a_sym) attr = a_sym end @attributes[attr] = value.to_s end # Handles the 'easy' API that allows navigating a simple XML by # referencing attributes by name. # - +id+ [Symbol] element or attribute name # *return* [String|nil] the attribute value # _raise_ [NoMethodError] if no match is found def method_missing(id, *args, &block) ids = id.to_s if instance_variable_defined?(:@attributes) return @attributes[id] if @attributes.has_key?(id) return @attributes[ids] if @attributes.has_key?(ids) end raise NoMethodError.new("#{ids} not found", name) end end # HasAttrs end # Ox ox-2.14.17/lib/ox/instruct.rb000066400000000000000000000023461445411231300157130ustar00rootroot00000000000000module Ox # An Instruct represents a processing instruction of an XML document. It has a target, attributes, and a value or # content. The content will be all characters with the exception of the target. If the content follows a regular # attribute format then the attributes will be set to the parsed values. If it does not follow the attribute formate # then the attributes will be empty. class Instruct < Node include HasAttrs # The content of the processing instruction. attr_accessor :content # Creates a new Instruct with the specified name. # - +name+ [String] name of the Instruct def initialize(name) super @attributes = nil @content = nil end alias target value # Returns true if this Object and other are of the same type and have the # equivalent value and the equivalent elements otherwise false is returned. # - +other+ [Object] Object compare _self_ to. # *return* [Boolean] true if both Objects are equivalent, otherwise false. def eql?(other) return false unless super(other) return false unless attributes == other.attributes return false unless content == other.content true end alias == eql? end # Instruct end # Ox ox-2.14.17/lib/ox/node.rb000066400000000000000000000012371445411231300147630ustar00rootroot00000000000000module Ox # The Node is the base class for all other in the Ox module. class Node # String value associated with the Node. attr_accessor :value # Creates a new Node with the specified String value. # - +value+ [String] string value for the Node def initialize(value) @value = value.to_s end # Returns true if this Object and other are of the same type and have the # equivalent value otherwise false is returned. # - +other+ [Object] Object to compare _self_ to. def eql?(other) return false if (other.nil? or self.class != other.class) other.value == value end alias == eql? end # Node end # Ox ox-2.14.17/lib/ox/raw.rb000066400000000000000000000005721445411231300146300ustar00rootroot00000000000000module Ox # Raw elements are used to inject existing XML strings into a document # WARNING: Use of this feature can result in invalid XML, since `value` is # injected as-is. class Raw < Node # Creates a new Raw element with the specified value. # - +value+ [String] string value for the comment def initialize(value) super end end # Raw end # Ox ox-2.14.17/lib/ox/sax.rb000066400000000000000000000055451445411231300146370ustar00rootroot00000000000000module Ox # A SAX style parse handler. The Ox::Sax handler class should be subclasses # and then used with the Ox.sax_parse() method. The Sax methods will then be # called as the file is parsed. This is best suited for very large files or # IO streams.

# # *Example* # # require 'ox' # # class MySax < ::Ox::Sax # def initialize() # @element_names = [] # end # # def start_element(name) # @element_names << name # end # end # # any = MySax.new() # File.open('any.xml', 'r') do |f| # Ox.sax_parse(any, f) # end # # To make the desired methods active while parsing the desired method should # be made public in the subclasses. If the methods remain private they will # not be called during parsing. The 'name' argument in the callback methods # will be a Symbol. The 'str' arguments will be a String. The 'value' # arguments will be Ox::Sax::Value objects. Since both the text() and the # value() methods are called for the same element in the XML document the the # text() method is ignored if the value() method is defined or public. The # same is true for attr() and attr_value(). When all attributes have been read # the attr_done() callback will be invoked. # # def instruct(target); end # def end_instruct(target); end # def attr(name, str); end # def attr_value(name, value); end # def attrs_done(); end # def doctype(str); end # def comment(str); end # def cdata(str); end # def text(str); end # def value(value); end # def start_element(name); end # def end_element(name); end # def error(message, line, column); end # def abort(name); end # # Initializing _line_ attribute in the initializer will cause that variable to # be updated before each callback with the XML line number. The same is true # for the _column_ attribute but it will be updated with the column in the XML # file that is the start of the element or node just read. @pos if defined # will hold the number of bytes from the start of the document. class Sax # Create a new instance of the Sax handler class. def initialize # @pos = nil # @line = nil # @column = nil end # To make the desired methods active while parsing the desired method # should be made public in the subclasses. If the methods remain private # they will not be called during parsing. private def instruct(target); end def end_instruct(target); end def attr(name, str); end def attr_value(name, value); end def attrs_done; end def doctype(str); end def comment(str); end def cdata(str); end def text(str); end def value(value); end def start_element(name); end def end_element(name); end def error(message, line, column); end def abort(name); end end # Sax end # Ox ox-2.14.17/lib/ox/version.rb000066400000000000000000000001071445411231300155160ustar00rootroot00000000000000module Ox # Current version of the module. VERSION = '2.14.17' end ox-2.14.17/lib/ox/xmlrpc_adapter.rb000066400000000000000000000016571445411231300170510ustar00rootroot00000000000000require 'ox' module Ox # This is an alternative parser for the stdlib xmlrpc library. It makes # use of Ox and is based on REXMLStreamParser. To use it set is as the # parser for an XMLRPC client: # # require 'xmlrpc/client' # require 'ox/xmlrpc_adapter' # client = XMLRPC::Client.new2('http://some_server/rpc') # client.set_parser(Ox::StreamParser.new) class StreamParser < XMLRPC::XMLParser::AbstractStreamParser # Create a new instance. def initialize super @parser_class = OxParser end # The SAX wrapper. class OxParser < Ox::Sax include XMLRPC::XMLParser::StreamParserMixin alias text character alias end_element endElement alias start_element startElement # Initiates the sax parser with the provided string. def parse(str) Ox.sax_parse(self, StringIO.new(str), symbolize: false, convert_special: true) end end end end ox-2.14.17/misc/000077500000000000000000000000001445411231300132455ustar00rootroot00000000000000ox-2.14.17/misc/notes000066400000000000000000000024601445411231300143220ustar00rootroot00000000000000;; -*- mode: outline; outline-regexp: " *[-\+]"; indent-tabs-mode: nil -*- ^c^d hide subtree ^c^s show subtree - Element - each - locate with pattern) - rdoc - --coverage-report for coverage (does not generate docs) - rdoc --main README.md --title Ox --exclude extconf.rb lib ext/ox README.md - todo - taint deprecated - implement a marked array or linked list in pinfo - not super efficient but it should work - search from tail - grow if needed. start with none and grow as needed in blocks of ?? - HTML (5) builder - should be correct for all elements - pedantic - add hints and overaly to parse.c - continuous sax parser - parse input stream and continue waiting for next one - add UTF-16 support U+0000..U+D7FF, U+E000..U+EFFF 00000xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx U+10000..U+10FFFF uuuuuxxxxxxyyyyyyyyyy 110110wwwwxxxxxx 110111yyyyyyyyyy (where uuuuu = wwww + 1) - hints xmllint --valid --noout --dtdvalid ../misc/ox.dtd --debug sample.xml #rsync -vru --exclude ".*" --exclude "*~" --exclude "#*" --exclude misc --exclude "*.o" ~/code/ox/ ~/git/ox rsync -vrI --exclude ".*" --exclude "*~" --exclude "#*" --exclude misc --exclude "*.o" ~/code/ox/ ~/git/ox rsync -vrI --exclude ".*" --exclude "*~" --exclude "#*" --exclude misc --exclude "*.o" ~/git/ox/ ~/code/ox ox-2.14.17/misc/ox.dtd000066400000000000000000000035221445411231300143720ustar00rootroot00000000000000 ox-2.14.17/misc/sample.xml000066400000000000000000001326241445411231300152600ustar00rootroot00000000000000 .. 1309872137.000000 1309872137.000000 510 ohler staff user rwx group r-x other r-x doc 1302099563.000000 1302099563.000000 68 ohler staff user rwx group r-x other r-x ext 1302099552.000000 1302099552.000000 102 ohler staff user rwx group r-x other r-x ox 1309874864.000000 1309874864.000000 1020 ohler staff user rwx group r-x other r-x base64.c 1302604726.000000 1302604726.000000 4536 ohler staff user rw- group r-- other r-- base64.h 1302604726.000000 1302604726.000000 1919 ohler staff user rw- group r-- other r-- base64.o 1309873370.000000 1309873370.000000 6100 ohler staff user rw- group r-- other r-- cache.c 1302604726.000000 1302604726.000000 5211 ohler staff user rw- group r-- other r-- cache.h 1302604726.000000 1302604726.000000 1877 ohler staff user rw- group r-- other r-- cache.o 1309873370.000000 1309873370.000000 8764 ohler staff user rw- group r-- other r-- cache16.z 1302099552.000000 1302099552.000000 2596 ohler staff user rw- group r-- other r-- cache8.c 1302604726.000000 1302604726.000000 1844 ohler staff user rw- group r-- other r-- cache8.h 1302604726.000000 1302604726.000000 1915 ohler staff user rw- group r-- other r-- cache8.o 1309873370.000000 1309873370.000000 11272 ohler staff user rw- group r-- other r-- cache8_test.c 1302604726.000000 1302604726.000000 2542 ohler staff user rw- group r-- other r-- cache8_test.o 1309873370.000000 1309873370.000000 3952 ohler staff user rw- group r-- other r-- cache_test.c 1302604726.000000 1302604726.000000 2493 ohler staff user rw- group r-- other r-- cache_test.o 1309873370.000000 1309873370.000000 4856 ohler staff user rw- group r-- other r-- dump.c 1309866269.000000 1309866269.000000 26622 ohler staff user rw- group r-- other r-- dump.o 1309873371.000000 1309873371.000000 63344 ohler staff user rw- group r-- other r-- extconf.rb 1302604726.000000 1302604726.000000 155 ohler staff user rw- group r-- other r-- gen_load.c 1302604726.000000 1302604726.000000 5948 ohler staff user rw- group r-- other r-- gen_load.o 1309873371.000000 1309873371.000000 14520 ohler staff user rw- group r-- other r-- Makefile 1309515102.000000 1309515102.000000 5423 ohler staff user rw- group r-- other r-- obj_load.c 1309874863.000000 1309874863.000000 23657 ohler staff user rw- group r-- other r-- obj_load.o 1309874864.000000 1309874864.000000 42948 ohler staff user rw- group r-- other r-- ox.bundle 1309874864.000000 1309874864.000000 75208 ohler staff user rwx group r-x other r-x ox.c 1309873745.000000 1309873745.000000 15782 ohler staff user rw- group r-- other r-- ox.h 1309872911.000000 1309872911.000000 6158 ohler staff user rw- group r-- other r-- ox.o 1309874178.000000 1309874178.000000 38320 ohler staff user rw- group r-- other r-- parse.c 1309872884.000000 1309872884.000000 16499 ohler staff user rw- group r-- other r-- parse.o 1309873372.000000 1309873372.000000 28616 ohler staff user rw- group r-- other r-- lib 1302604726.000000 1302604726.000000 136 ohler staff user rwx group r-x other r-x ox 1309866905.000000 1309866905.000000 340 ohler staff user rwx group r-x other r-x bag.rb 1309866905.000000 1309866905.000000 2924 ohler staff user rw- group r-- other r-- bag.rb~ 1309866847.000000 1309866847.000000 2924 ohler staff user rw- group r-- other r-- cdata.rb 1302604726.000000 1302604726.000000 233 ohler staff user rw- group r-- other r-- comment.rb 1302604726.000000 1302604726.000000 297 ohler staff user rw- group r-- other r-- doctype.rb 1302604726.000000 1302604726.000000 291 ohler staff user rw- group r-- other r-- document.rb 1302604726.000000 1302604726.000000 792 ohler staff user rw- group r-- other r-- element.rb 1309513804.000000 1309513804.000000 2273 ohler staff user rw- group r-- other r-- node.rb 1302604726.000000 1302604726.000000 645 ohler staff user rw- group r-- other r-- ox.rb 1302604726.000000 1302604726.000000 3168 ohler staff user rw- group r-- other r-- LICENSE 1302604726.000000 1302604726.000000 1488 ohler staff user rw- group r-- other r-- misc 1302099562.000000 1302099562.000000 102 ohler staff user rwx group r-x other r-x load_cfg.rb 1302099562.000000 1302099562.000000 1273 ohler staff user rwx group r-x other r-x notes 1309872137.000000 1309872137.000000 776 ohler staff user rw- group r-- other r-- ox-1.0.2.gem 1309515131.000000 1309515131.000000 40448 ohler staff user rw- group r-- other r-- ox.gemspec 1309866269.000000 1309866269.000000 747 ohler staff user rw- group r-- other r-- README.rdoc 1309513804.000000 1309513804.000000 4633 ohler staff user rw- group r-- other r-- test 1309873425.000000 1309873425.000000 680 ohler staff user rwx group r-x other r-x cache16_test.rb 1302604726.000000 1302604726.000000 201 ohler staff user rwx group r-x other r-x cache8_test.rb 1302604726.000000 1302604726.000000 200 ohler staff user rwx group r-x other r-x cache_test.rb 1302604726.000000 1302604726.000000 199 ohler staff user rwx group r-x other r-x files.rb 1302604726.000000 1302604726.000000 712 ohler staff user rwx group r-x other r-x func.rb 1309873425.000000 1309873425.000000 5408 ohler staff user rwx group r-x other r-x gen_sample.rb 1302604726.000000 1302604726.000000 330 ohler staff user rw- group r-- other r-- obj_sample.rb 1302604726.000000 1302604726.000000 326 ohler staff user rw- group r-- other r-- ox 1302604726.000000 1302604726.000000 476 ohler staff user rwx group r-x other r-x change.rb 1302604726.000000 1302604726.000000 330 ohler staff user rw- group r-- other r-- dir.rb 1302604726.000000 1302604726.000000 255 ohler staff user rw- group r-- other r-- doc.rb 1302604726.000000 1302604726.000000 831 ohler staff user rw- group r-- other r-- file.rb 1302604726.000000 1302604726.000000 1085 ohler staff user rw- group r-- other r-- group.rb 1302604726.000000 1302604726.000000 239 ohler staff user rw- group r-- other r-- hasprops.rb 1302604726.000000 1302604726.000000 344 ohler staff user rw- group r-- other r-- layer.rb 1302604726.000000 1302604726.000000 189 ohler staff user rw- group r-- other r-- line.rb 1302604726.000000 1302604726.000000 369 ohler staff user rw- group r-- other r-- oval.rb 1302604726.000000 1302604726.000000 166 ohler staff user rw- group r-- other r-- rect.rb 1302604726.000000 1302604726.000000 166 ohler staff user rw- group r-- other r-- shape.rb 1302604726.000000 1302604726.000000 658 ohler staff user rw- group r-- other r-- text.rb 1302604726.000000 1302604726.000000 470 ohler staff user rw- group r-- other r-- perf_gen.rb 1302604726.000000 1302604726.000000 5216 ohler staff user rwx group r-x other r-x perf_mars.rb 1302604726.000000 1302604726.000000 2423 ohler staff user rwx group r-x other r-x perf_obj.rb 1302604726.000000 1302604726.000000 5398 ohler staff user rwx group r-x other r-x perf_pod.rb 1302604726.000000 1302604726.000000 2373 ohler staff user rwx group r-x other r-x perf_write.rb 1302604726.000000 1302604726.000000 1675 ohler staff user rwx group r-x other r-x Sample.graffle 1302604726.000000 1302604726.000000 46577 ohler staff user rw- group r-- other r-- sample.marshal 1309874878.000000 1309874878.000000 12412 ohler staff user rw- group r-- other r-- sample.rb 1302604726.000000 1302604726.000000 1488 ohler staff user rwx group r-x other r-x sample.xml 1309874878.000000 1309874878.000000 28053 ohler staff user rw- group r-- other r-- test.rb 1302604726.000000 1302604726.000000 1225 ohler staff user rwx group r-x other r-x xml 1302604726.000000 1302604726.000000 510 ohler staff user rwx group r-x other r-x attr.xml 1302604726.000000 1302604726.000000 40 ohler staff user rw- group r-- other r-- comment.xml 1302604726.000000 1302604726.000000 44 ohler staff user rw- group r-- other r-- empty.xml 1302604726.000000 1302604726.000000 23 ohler staff user rw- group r-- other r-- env.xml 1302604726.000000 1302604726.000000 1097 ohler staff user rw- group r-- other r-- loner.xml 1302604726.000000 1302604726.000000 30 ohler staff user rw- group r-- other r-- mixed.xml 1302604726.000000 1302604726.000000 120 ohler staff user rw- group r-- other r-- nest.xml 1302604726.000000 1302604726.000000 183 ohler staff user rw- group r-- other r-- sample.xml 1302604726.000000 1302604726.000000 68 ohler staff user rw- group r-- other r-- wFractal.xml 1302604726.000000 1302604726.000000 29077 ohler staff user rw- group r-- other r-- wFractal_report.xml 1302604726.000000 1302604726.000000 44231 ohler staff user rw- group r-- other r-- wr.xml 1302604726.000000 1302604726.000000 15822 ohler staff user rw- group r-- other r-- zoo.xml 1302604726.000000 1302604726.000000 420 ohler staff user rw- group r-- other r-- zoo2.xml 1302604726.000000 1302604726.000000 1138 ohler staff user rw- group r-- other r-- ox-2.14.17/misc/simple.xml000066400000000000000000000003031445411231300152540ustar00rootroot00000000000000 510 xyz ox-2.14.17/ox.gemspec000066400000000000000000000022451445411231300143100ustar00rootroot00000000000000require 'date' require File.join(File.dirname(__FILE__), 'lib/ox/version') Gem::Specification.new do |s| s.name = 'ox' s.version = Ox::VERSION s.authors = 'Peter Ohler' s.email = 'peter@ohler.com' s.homepage = 'http://www.ohler.com/ox' s.summary = 'A fast XML parser and object serializer.' s.description = %{A fast XML parser and object serializer that uses only standard C lib. Optimized XML (Ox), as the name implies was written to provide speed optimized XML handling. It was designed to be an alternative to Nokogiri and other Ruby XML parsers for generic XML parsing and as an alternative to Marshal for Object serialization. } s.licenses = ['MIT'] s.files = Dir['{lib,ext}/**/*.{rb,h,c}'] + ['LICENSE', 'README.md', 'CHANGELOG.md'] s.extensions = ['ext/ox/extconf.rb'] # s.executables = [] s.require_paths = ['lib', 'ext'] s.extra_rdoc_files = ['README.md', 'CHANGELOG.md'] s.rdoc_options = ['--main', 'README.md', '--title', 'Ox', '--exclude', 'extconf.rb', 'lib', 'ext/ox', 'README.md'] s.required_ruby_version = '>= 2.7.0' s.add_development_dependency 'rake-compiler', '>= 1.2', '< 2.0' s.metadata['rubygems_mfa_required'] = 'true' end ox-2.14.17/test/000077500000000000000000000000001445411231300132715ustar00rootroot00000000000000ox-2.14.17/test/Sample.graffle000066400000000000000000001327611445411231300160540ustar00rootroot00000000000000 ActiveLayerIndex 0 ApplicationVersion com.omnigroup.OmniGrafflePro 138.17.0.133677 AutoAdjust BackgroundGraphic Bounds {{0, 0}, {559.28, 782.89}} Class SolidGraphic ID 2 Style shadow Draws NO stroke Draws NO CanvasOrigin {0, 0} ColumnAlign 1 ColumnSpacing 36 CreationDate 2010-12-30 19:08:43 +0900 Creator Ohler Peter DisplayScale 1.000 cm = 1.000 cm FileType flat GraphDocumentVersion 6 GraphicsList Class LineGraphic Head ID 90 ID 95 Points {325.484, 404.043} {298.136, 404.177} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 91 Class LineGraphic Head ID 89 ID 94 Points {254.618, 404.043} {227.27, 404.177} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 90 Class LineGraphic Head ID 88 ID 93 Points {183.752, 404.043} {156.404, 404.177} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 89 Class LineGraphic Head ID 87 ID 92 Points {112.886, 404.043} {85.538, 404.177} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 88 Bounds {{325.984, 382.677}, {42.5196, 42.5196}} Class ShapedGraphic ID 91 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{255.118, 382.677}, {42.5196, 42.5196}} Class ShapedGraphic ID 90 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{184.252, 382.677}, {42.5196, 42.5196}} Class ShapedGraphic ID 89 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{113.386, 382.677}, {42.5196, 42.5196}} Class ShapedGraphic ID 88 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{42.5197, 382.677}, {42.5196, 42.5196}} Class ShapedGraphic ID 87 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{311.811, 368.504}, {70.8661, 70.8661}} Class ShapedGraphic ID 86 Shape Rectangle Style fill Color b 0.501961 g 0.501961 r 0.501961 shadow Draws NO Bounds {{240.945, 368.504}, {70.8661, 70.8661}} Class ShapedGraphic ID 85 Shape Rectangle Style fill Color b 0 g 0.501961 r 0 shadow Draws NO Bounds {{170.079, 368.504}, {70.8661, 70.8661}} Class ShapedGraphic ID 84 Shape Rectangle Style fill Color b 0 g 1 r 1 shadow Draws NO Bounds {{99.2127, 368.504}, {70.8661, 70.8661}} Class ShapedGraphic ID 83 Shape Rectangle Style fill Color b 1 g 0.501961 r 0 shadow Draws NO Bounds {{28.3465, 368.504}, {70.8661, 70.8661}} Class ShapedGraphic ID 82 Shape Rectangle Style shadow Draws NO Class LineGraphic Head ID 76 ID 81 Points {325.484, 319.004} {298.136, 319.138} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 77 Class LineGraphic Head ID 75 ID 80 Points {254.618, 319.004} {227.27, 319.138} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 76 Class LineGraphic Head ID 74 ID 79 Points {183.752, 319.004} {156.404, 319.138} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 75 Class LineGraphic Head ID 73 ID 78 Points {112.886, 319.004} {85.538, 319.138} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 74 Bounds {{325.984, 297.638}, {42.5196, 42.5196}} Class ShapedGraphic ID 77 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{255.118, 297.638}, {42.5196, 42.5196}} Class ShapedGraphic ID 76 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{184.252, 297.638}, {42.5196, 42.5196}} Class ShapedGraphic ID 75 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{113.386, 297.638}, {42.5196, 42.5196}} Class ShapedGraphic ID 74 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{42.5197, 297.638}, {42.5196, 42.5196}} Class ShapedGraphic ID 73 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{311.811, 283.465}, {70.8661, 70.8661}} Class ShapedGraphic ID 72 Shape Rectangle Style fill Color b 0.501961 g 0.501961 r 0.501961 shadow Draws NO Bounds {{240.945, 283.465}, {70.8661, 70.8661}} Class ShapedGraphic ID 71 Shape Rectangle Style fill Color b 0 g 0.501961 r 0 shadow Draws NO Bounds {{170.079, 283.465}, {70.8661, 70.8661}} Class ShapedGraphic ID 70 Shape Rectangle Style fill Color b 0 g 1 r 1 shadow Draws NO Bounds {{99.2127, 283.465}, {70.8661, 70.8661}} Class ShapedGraphic ID 69 Shape Rectangle Style fill Color b 1 g 0.501961 r 0 shadow Draws NO Bounds {{28.3465, 283.465}, {70.8661, 70.8661}} Class ShapedGraphic ID 68 Shape Rectangle Style shadow Draws NO Class LineGraphic Head ID 62 ID 67 Points {325.484, 233.964} {298.136, 234.098} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 63 Class LineGraphic Head ID 61 ID 66 Points {254.618, 233.964} {227.27, 234.098} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 62 Class LineGraphic Head ID 60 ID 65 Points {183.752, 233.964} {156.404, 234.098} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 61 Class LineGraphic Head ID 59 ID 64 Points {112.886, 233.964} {85.538, 234.098} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 60 Bounds {{325.984, 212.598}, {42.5196, 42.5196}} Class ShapedGraphic ID 63 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{255.118, 212.598}, {42.5196, 42.5196}} Class ShapedGraphic ID 62 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{184.252, 212.598}, {42.5196, 42.5196}} Class ShapedGraphic ID 61 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{113.386, 212.598}, {42.5196, 42.5196}} Class ShapedGraphic ID 60 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{42.5197, 212.598}, {42.5196, 42.5196}} Class ShapedGraphic ID 59 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{311.811, 198.425}, {70.8661, 70.8661}} Class ShapedGraphic ID 58 Shape Rectangle Style fill Color b 0.501961 g 0.501961 r 0.501961 shadow Draws NO Bounds {{240.945, 198.425}, {70.8661, 70.8661}} Class ShapedGraphic ID 57 Shape Rectangle Style fill Color b 0 g 0.501961 r 0 shadow Draws NO Bounds {{170.079, 198.425}, {70.8661, 70.8661}} Class ShapedGraphic ID 56 Shape Rectangle Style fill Color b 0 g 1 r 1 shadow Draws NO Bounds {{99.2127, 198.425}, {70.8661, 70.8661}} Class ShapedGraphic ID 55 Shape Rectangle Style fill Color b 1 g 0.501961 r 0 shadow Draws NO Bounds {{28.3465, 198.425}, {70.8661, 70.8661}} Class ShapedGraphic ID 54 Shape Rectangle Style shadow Draws NO Class LineGraphic Head ID 48 ID 53 Points {325.484, 148.823} {298.138, 148.828} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 49 Class LineGraphic Head ID 47 ID 52 Points {254.618, 148.823} {227.272, 148.828} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 48 Class LineGraphic Head ID 46 ID 51 Points {183.752, 148.823} {156.406, 148.828} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 47 Class LineGraphic Head ID 45 ID 50 Points {112.886, 148.823} {85.5393, 148.828} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 46 Bounds {{325.984, 127.559}, {42.5196, 42.5196}} Class ShapedGraphic ID 49 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{255.118, 127.559}, {42.5196, 42.5196}} Class ShapedGraphic ID 48 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{184.252, 127.559}, {42.5196, 42.5196}} Class ShapedGraphic ID 47 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{113.386, 127.559}, {42.5196, 42.5196}} Class ShapedGraphic ID 46 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{42.5197, 127.559}, {42.5196, 42.5196}} Class ShapedGraphic ID 45 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{311.811, 113.386}, {70.8661, 70.8661}} Class ShapedGraphic ID 44 Shape Rectangle Style fill Color b 0.501961 g 0.501961 r 0.501961 shadow Draws NO Bounds {{240.945, 113.386}, {70.8661, 70.8661}} Class ShapedGraphic ID 43 Shape Rectangle Style fill Color b 0 g 0.501961 r 0 shadow Draws NO Bounds {{170.079, 113.386}, {70.8661, 70.8661}} Class ShapedGraphic ID 42 Shape Rectangle Style fill Color b 0 g 1 r 1 shadow Draws NO Bounds {{99.2127, 113.386}, {70.8661, 70.8661}} Class ShapedGraphic ID 41 Shape Rectangle Style fill Color b 1 g 0.501961 r 0 shadow Draws NO Bounds {{28.3465, 113.386}, {70.8661, 70.8661}} Class ShapedGraphic ID 40 Shape Rectangle Style shadow Draws NO Class LineGraphic Head ID 13 ID 39 Points {325.484, 63.8035} {298.138, 63.8335} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 14 Class LineGraphic Head ID 12 ID 38 Points {254.618, 63.8204} {227.271, 63.8715} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 13 Class LineGraphic Head ID 11 ID 37 Points {183.752, 63.8077} {156.405, 63.843} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 12 Class LineGraphic Head ID 10 ID 35 Points {112.886, 63.7796} {85.5394, 63.7796} Style stroke HeadArrow 0 LineType 1 TailArrow 0 Tail ID 11 Bounds {{325.984, 42.5199}, {42.5196, 42.5196}} Class ShapedGraphic ID 14 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{255.118, 42.5199}, {42.5196, 42.5196}} Class ShapedGraphic ID 13 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{184.252, 42.5198}, {42.5196, 42.5196}} Class ShapedGraphic ID 12 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{113.386, 42.5198}, {42.5196, 42.5196}} Class ShapedGraphic ID 11 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{42.5197, 42.5197}, {42.5196, 42.5196}} Class ShapedGraphic ID 10 Shape Circle Style fill Color b 0 g 0 r 1 shadow Draws NO Bounds {{311.811, 28.3465}, {70.8661, 70.8661}} Class ShapedGraphic ID 9 Shape Rectangle Style fill Color b 0.501961 g 0.501961 r 0.501961 shadow Draws NO Bounds {{240.945, 28.3465}, {70.8661, 70.8661}} Class ShapedGraphic ID 8 Shape Rectangle Style fill Color b 0 g 0.501961 r 0 shadow Draws NO Bounds {{170.079, 28.3465}, {70.8661, 70.8661}} Class ShapedGraphic ID 7 Shape Rectangle Style fill Color b 0 g 1 r 1 shadow Draws NO Bounds {{99.2127, 28.3465}, {70.8661, 70.8661}} Class ShapedGraphic ID 6 Shape Rectangle Style fill Color b 1 g 0.501961 r 0 shadow Draws NO Bounds {{28.3465, 28.3465}, {70.8661, 70.8661}} Class ShapedGraphic ID 3 Shape Rectangle Style shadow Draws NO GridInfo DrawMajorGrid NO GridSpacing 28.346458435058594 MajorGridSpacing 1 ShowsGrid YES SnapsToGrid YES GuidesLocked NO GuidesVisible YES HPages 1 ImageCounter 1 KeepToScale Layers Lock NO Name Layer 1 Print YES View YES LayoutInfo Animate NO circoMinDist 18 circoSeparation 0.0 layoutEngine dot neatoSeparation 0.0 twopiSeparation 0.0 LinksVisible NO MagnetsVisible NO MasterSheets ModificationDate 2010-12-30 19:12:47 +0900 Modifier Ohler Peter NotesVisible NO Orientation 2 OriginVisible NO PageBreaks YES PrintInfo NSBottomMargin float 41 NSLeftMargin float 18 NSPaperName string A4 NSPaperSize size {595.28, 841.89} NSRightMargin float 18 NSTopMargin float 18 PrintOnePage ReadOnly NO RowAlign 1 RowSpacing 36 SheetTitle Canvas 1 SmartAlignmentGuidesActive NO SmartDistanceGuidesActive NO UniqueID 1 UseEntirePage VPages 1 WindowInfo CurrentSheet 0 ExpandedCanvases name Canvas 1 Frame {{976, 361}, {694, 902}} ListView OutlineWidth 142 RightSidebar ShowRuler Sidebar SidebarWidth 120 VisibleRegion {{0, 0}, {559, 783}} Zoom 1 ZoomValues Canvas 1 1 1 saveQuickLookFiles NO ox-2.14.17/test/c/000077500000000000000000000000001445411231300135135ustar00rootroot00000000000000ox-2.14.17/test/c/cache16.c000066400000000000000000000047061445411231300151000ustar00rootroot00000000000000 #include "cache16.h" #include #include #include #include #include struct _Cache16 { VALUE value; struct _Cache16 *slots[16]; }; static void slot_print(Cache16 cache, unsigned int depth); static void v2s(VALUE v, char *buf, unsigned long len); void ox_cache16_new(Cache16 *cache) { Cache16 *cp; int i; if (0 == (*cache = (Cache16)malloc(sizeof(struct _Cache16)))) { rb_raise(rb_eStandardError, "not enough memory\n"); } (*cache)->value = Qundef; for (i = 16, cp = (*cache)->slots; 0 < i; i--, cp++) { *cp = 0; } } VALUE ox_cache16_get(Cache16 cache, const char *key, VALUE **slot) { unsigned char *k = (unsigned char *)key; Cache16 *cp; for (; '\0' != *k; k++) { cp = cache->slots + (unsigned int)(*k >> 4); // upper 4 bits if (0 == *cp) { ox_cache16_new(cp); } cache = *cp; cp = cache->slots + (unsigned int)(*k & 0x0F); // lower 4 bits if (0 == *cp) { ox_cache16_new(cp); } cache = *cp; } *slot = &cache->value; return cache->value; } void ox_cache16_print(Cache16 cache) { // printf("-------------------------------------------\n"); slot_print(cache, 0); } static void slot_print(Cache16 c, unsigned int depth) { char indent[256]; Cache16 *cp; unsigned int i; if (sizeof(indent) - 1 < depth) { depth = ((int)sizeof(indent) - 1); } memset(indent, ' ', depth); indent[depth] = '\0'; for (i = 0, cp = c->slots; i < 16; i++, cp++) { if (0 == *cp) { // printf("%s%02u:\n", indent, i); } else { if (Qundef == (*cp)->value) { printf("%s%02u:\n", indent, i); } else { char value[1024]; const char *clas; if (Qundef == (*cp)->value) { strcpy(value, "undefined"); clas = ""; } else { v2s((*cp)->value, value, sizeof(value)); clas = rb_class2name(rb_obj_class((*cp)->value)); } printf("%s%02u: %s (%s)\n", indent, i, value, clas); } slot_print(*cp, depth + 2); } } } static void v2s(VALUE v, char *buf, unsigned long len) { VALUE rs = rb_String(v); snprintf(buf, len, "%s", StringValuePtr(rs)); } ox-2.14.17/test/c/cache8_test.c000066400000000000000000000023671445411231300160610ustar00rootroot00000000000000/* cache8_test.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "cache8.h" #include static slot_t data[] = {0x000000A0A0A0A0A0ULL, 0x0000000000ABCDEFULL, 0x0123456789ABCDEFULL, 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000003ULL, 0x0000000000000004ULL, 0}; void ox_cache8_test() { Cache8 c; slot_t v; slot_t *d; slot_t cnt = 1; slot_t *slot = 0; ox_cache8_new(&c); for (d = data; 0 != *d; d++) { v = ox_cache8_get(c, *d, &slot); if (0 == v) { if (0 == slot) { printf("*** failed to get a slot for 0x%016llx\n", (unsigned long long)*d); } else { printf("*** adding 0x%016llx to cache with value %llu\n", (unsigned long long)*d, (unsigned long long)cnt); *slot = cnt++; } } else { printf("*** get on 0x%016llx returned %llu\n", (unsigned long long)*d, (unsigned long long)v); } /*ox_cache8_print(c); */ } ox_cache8_print(c); } ox-2.14.17/test/c/cache_test.c000066400000000000000000000021521445411231300157610ustar00rootroot00000000000000/* cache_test.c * Copyright (c) 2011, Peter Ohler * All rights reserved. */ #include "cache.h" static const char *data[] = { #if 1 "one", "two", "one", "onex", "oney", "one", "tw", "onexyzabcdefgh", #else "abc", "abcd", "ab", "a", "abcdefghijklmnop", #endif 0}; void ox_cache_test() { Cache c; const char **d; VALUE v; VALUE *slot = 0; ; ox_cache_new(&c); for (d = data; 0 != *d; d++) { /*printf("*** cache_get on %s\n", *d);*/ v = ox_cache_get(c, *d, &slot, 0); if (Qundef == v) { if (0 == slot) { /*printf("*** failed to get a slot for %s\n", *d); */ } else { /*printf("*** added '%s' to cache\n", *d); */ v = ID2SYM(rb_intern(*d)); *slot = v; } } else { VALUE rs = rb_String(v); printf("*** get on '%s' returned '%s' (%s)\n", *d, StringValuePtr(rs), rb_class2name(rb_obj_class(v))); } /*ox_cache_print(c);*/ } ox_cache_print(c); } ox-2.14.17/test/cache8_test.rb000077500000000000000000000002671445411231300160200ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '../lib' $: << '../ext' if __FILE__ == $0 && (i = ARGV.index('-I')) x, path = ARGV.slice!(i, 2) $: << path end require 'ox' Ox.cache8_test ox-2.14.17/test/cache_test.rb000077500000000000000000000002661445411231300157270ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '../lib' $: << '../ext' if __FILE__ == $0 && (i = ARGV.index('-I')) x, path = ARGV.slice!(i, 2) $: << path end require 'ox' Ox.cache_test ox-2.14.17/test/files.rb000077500000000000000000000007411445411231300147250ustar00rootroot00000000000000#!/usr/bin/env ruby -wW2 if $0 == __FILE__ $: << '.' $: << '..' $: << '../lib' $: << '../ext' end require 'sample/file' require 'sample/dir' def files(dir) d = Sample::Dir.new(dir) Dir.new(dir).each do |fn| next if fn.start_with?('.') filename = File.join(dir, fn) # filename = '.' == dir ? fn : File.join(dir, fn) if File.directory?(filename) d << files(filename) else d << Sample::File.new(filename) end end # pp d d end ox-2.14.17/test/gen_sample.rb000066400000000000000000000005061445411231300157310ustar00rootroot00000000000000require 'ox' doc = Ox::Document.new(version: '1.0') top = Ox::Element.new('top') top[:name] = 'sample' doc << top mid = Ox::Element.new('middle') mid[:name] = 'second' top << mid bot = Ox::Element.new('bottom') bot[:name] = 'third' mid << bot xml = Ox.dump(doc) puts xml doc2 = Ox.parse(xml) puts "Same? #{doc == doc2}" ox-2.14.17/test/obj_sample.rb000066400000000000000000000005031445411231300157270ustar00rootroot00000000000000require 'ox' class Sample attr_accessor :a, :b, :c def initialize(a, b, c) @a = a @b = b @c = c end end # File # Create Object obj = Sample.new(1, 'bee', ['x', :y, 7.0]) # Now dump the Object to an XML String. xml = Ox.dump(obj) # Convert the object back into a Sample Object. obj2 = Ox.parse_obj(xml) ox-2.14.17/test/ox/000077500000000000000000000000001445411231300137175ustar00rootroot00000000000000ox-2.14.17/test/ox/change.rb000066400000000000000000000005021445411231300154660ustar00rootroot00000000000000module Test module Ox class Change attr_accessor :time attr_accessor :user attr_accessor :comment def initialize(comment=nil, time=nil, user=nil) @user = user || ENV['USER'] @time = time || Time.now @comment = comment end end # Change end # Ox end # Test ox-2.14.17/test/ox/dir.rb000066400000000000000000000003661445411231300150270ustar00rootroot00000000000000require 'etc' module Test module Ox class Dir < File attr_accessor :files def initialize(filename) super @files = [] end def <<(f) @files << f end end # Dir end # Ox end # Test ox-2.14.17/test/ox/doc.rb000066400000000000000000000014571445411231300150200ustar00rootroot00000000000000require 'test/ox/hasprops' require 'test/ox/group' require 'test/ox/layer' require 'test/ox/line' require 'test/ox/shape' require 'test/ox/oval' require 'test/ox/rect' require 'test/ox/text' require 'test/ox/change' module Test module Ox class Doc include HasProps attr_accessor :title attr_accessor :create_time attr_accessor :user # Hash of layers in the document indexed by layer name. attr_reader :layers attr_reader :change_history def initialize(title) @title = title @user = ENV['USER'] @create_time = Time.now @layers = {} @change_history = [] end def add_change(comment, time=nil, user=nil) @change_history << Change.new(comment, time, user) end end # Doc end # Ox end # Test ox-2.14.17/test/ox/file.rb000066400000000000000000000020151445411231300151610ustar00rootroot00000000000000require 'etc' module Test module Ox class File attr_accessor :name, :ctime, :mtime, :size, :owner, :group, :permissions def initialize(filename) @name = ::File.basename(filename) stat = ::File.stat(filename) @ctime = stat.ctime @mtime = stat.mtime @size = stat.size @owner = Etc.getpwuid(stat.uid).name @group = Etc.getgrgid(stat.gid).name @permissions = { user: [0 != (stat.mode & 0x0100) ? 'r' : '-', 0 != (stat.mode & 0x0080) ? 'w' : '-', 0 != (stat.mode & 0x0040) ? 'x' : '-'].join(''), group: [0 != (stat.mode & 0x0020) ? 'r' : '-', 0 != (stat.mode & 0x0010) ? 'w' : '-', 0 != (stat.mode & 0x0008) ? 'x' : '-'].join(''), other: [0 != (stat.mode & 0x0004) ? 'r' : '-', 0 != (stat.mode & 0x0002) ? 'w' : '-', 0 != (stat.mode & 0x0001) ? 'x' : '-'].join('') } end end # File end # Ox end # Test ox-2.14.17/test/ox/group.rb000066400000000000000000000003321445411231300153760ustar00rootroot00000000000000module Test module Ox class Group attr_reader :members def initialize @members = [] end def <<(member) @members << member end end # Group end # Ox end # Test ox-2.14.17/test/ox/hasprops.rb000066400000000000000000000005031445411231300161010ustar00rootroot00000000000000module Test module Ox module HasProps def add_prop(key, value) @props = {} unless instance_variable_defined?(:@props) @props[key] = value end def props @props = {} unless instance_variable_defined?(:@props) @props end end # HashProps end # Ox end # Test ox-2.14.17/test/ox/layer.rb000066400000000000000000000002731445411231300153620ustar00rootroot00000000000000module Test module Ox class Layer < Group attr_accessor :name def initialize(name) super() @name = name end end # Layer end # Ox end # Test ox-2.14.17/test/ox/line.rb000066400000000000000000000005511445411231300151740ustar00rootroot00000000000000module Test module Ox class Line include HasProps attr_accessor :x, :y, :dx, :dy attr_accessor :color attr_accessor :thick def initialize(x, y, dx, dy, thick, color) @x = x @y = y @dx = dx @dy = dy @thick = thick @color = color end end # Line end # Ox end # Test ox-2.14.17/test/ox/oval.rb000066400000000000000000000002431445411231300152040ustar00rootroot00000000000000module Test module Ox class Oval < Shape def initialize(left, top, wide, high, color=nil) super end end # Oval end # Ox end # Test ox-2.14.17/test/ox/rect.rb000066400000000000000000000002431445411231300152000ustar00rootroot00000000000000module Test module Ox class Rect < Shape def initialize(left, top, wide, high, color=nil) super end end # Rect end # Ox end # Test ox-2.14.17/test/ox/shape.rb000066400000000000000000000011611445411231300153430ustar00rootroot00000000000000module Test module Ox class Shape include HasProps attr_accessor :bounds attr_accessor :color attr_accessor :border, :border_color def initialize(left, top, wide, high, color=nil) @bounds = [[left, top], [left + wide, top + high]] @color = color @border = 1 @border_color = :black end def left @bounds[0][0] end def top @bounds[0][1] end def width @bounds[1][0] - @bounds[0][0] end def height @bounds[1][1] - @bounds[0][1] end end # Shape end # Ox end # Test ox-2.14.17/test/ox/text.rb000066400000000000000000000007231445411231300152320ustar00rootroot00000000000000module Test module Ox class Text < Shape attr_accessor :text attr_accessor :font attr_accessor :font_size attr_accessor :just attr_accessor :text_color def initialize(text, left, top, wide, high, color=nil) super(left, top, wide, high, color) @text = text @font = 'helvetica' @font_size = 14 @just = 'left' @text_color = 'black' end end # Text end # Ox end # Test ox-2.14.17/test/parse_cmp.rb000077500000000000000000000127101445411231300155730ustar00rootroot00000000000000#!/usr/bin/env ruby -wW1 $: << '../lib' $: << '../ext' require 'optparse' require 'stringio' require 'ox' $verbose = 0 $iter = 100 opts = OptionParser.new opts.on('-v', 'increase verbosity') { $verbose += 1 } opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |i| $iter = i } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } files = opts.parse(ARGV) ### XML conversion to Hash using in memory Ox parsing ### def node_to_dict(element) dict = {} key = nil element.nodes.each do |n| raise 'A dict can only contain elements.' unless n.is_a?(Ox::Element) if key.nil? raise "Expected a key, not a #{n.name}." unless 'key' == n.name key = first_text(n) else dict[key] = node_to_value(n) key = nil end end dict end def node_to_array(element) a = [] element.nodes.each do |n| a.push(node_to_value(n)) end a end def node_to_value(node) raise 'A dict can only contain elements.' unless node.is_a?(Ox::Element) case node.name when 'key' raise 'Expected a value, not a key.' when 'string' value = first_text(node) when 'dict' value = node_to_dict(node) when 'array' value = node_to_array(node) when 'integer' value = first_text(node).to_i when 'real' value = first_text(node).to_f when 'true' value = true when 'false' value = false else raise "#{node.name} is not a know element type." end value end def first_text(node) node.nodes.each do |n| return n if n.is_a?(String) end nil end def parse_gen(xml) doc = Ox.parse(xml) plist = doc.root dict = nil plist.nodes.each do |n| if n.is_a?(Ox::Element) dict = node_to_dict(n) break end end dict end ### XML conversion to Hash using Ox SAX parser ### class Handler def initialize @key = nil @type = nil @plist = nil @stack = [] end def text(value) last = @stack.last if last.is_a?(Hash) and @key.nil? raise "Expected a key, not #{@type} with a value of #{value}." unless :key == @type @key = value else append(value) end end def start_element(name) if :dict == name dict = {} append(dict) @stack.push(dict) elsif :array == name a = [] append(a) @stack.push(a) elsif :true == name append(true) elsif :false == name append(false) else @type = name end end def end_element(name) @stack.pop if [:dict, :array].include?(name) end attr_reader :plist def append(value) unless value.is_a?(Array) or value.is_a?(Hash) case @type when :string # ignore when :key # ignore when :integer value = value.to_i when :real value = value.to_f end end last = @stack.last if last.is_a?(Hash) raise "Expected a key, not with a value of #{value}." if @key.nil? last[@key] = value @key = nil elsif last.is_a?(Array) last.push(value) elsif last.nil? @plist = value end end end def parse_sax(xml) io = StringIO.new(xml) start = Time.now handler = Handler.new Ox.sax_parse(handler, io) handler.plist end ### XML conversion to Hash using Ox Object parsing with gsub! replacements ### def convert_parse_obj(xml) xml = plist_to_obj_xml(xml) Ox.load(xml, mode: :object) end ### XML conversion to Hash using Ox Object parsing after gsub! replacements ### def parse_obj(xml) Ox.load(xml, mode: :object) end def plist_to_obj_xml(xml) xml = xml.gsub(%{ }, '') xml.gsub!(%{ }, '') { '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '', '' => '' }.each do |pat, rep| xml.gsub!(pat, rep) end xml end files.each do |filename| xml = File.read(filename) if 0 < $verbose d1 = parse_gen(xml) d2 = parse_sax(xml) d3 = convert_parse_obj(xml) puts "--- It is #{d1 == d2 and d2 == d3} that all parsers yield the same Hash. ---" end start = Time.now $iter.times do parse_gen(xml) end gen_time = Time.now - start start = Time.now $iter.times do parse_sax(xml) end sax_time = Time.now - start start = Time.now $iter.times do convert_parse_obj(xml) end conv_obj_time = Time.now - start xml = plist_to_obj_xml(xml) start = Time.now $iter.times do parse_obj(xml) end obj_time = Time.now - start puts "In memory parsing and conversion took #{gen_time} for #{$iter} iterations." puts "SAX parsing and conversion took #{sax_time} for #{$iter} iterations." puts "XML gsub Object parsing and conversion took #{conv_obj_time} for #{$iter} iterations." puts "Object parsing and conversion took #{obj_time} for #{$iter} iterations." end # Results for a run: # # > parse_cmp.rb Sample.graffle -i 1000 # In memory parsing and conversion took 4.135701 for 1000 iterations. # SAX parsing and conversion took 3.731695 for 1000 iterations. # XML gsub Object parsing and conversion took 3.292397 for 1000 iterations. # Object parsing and conversion took 0.808877 for 1000 iterations. ox-2.14.17/test/perf.rb000066400000000000000000000045731445411231300145630ustar00rootroot00000000000000class Perf def initialize @items = [] end def add(title, op, &blk) @items << Item.new(title, op, &blk) end def before(title, &blk) @items.each do |i| if title == i.title i.set_before(&blk) break end end end def run(iter) base = Item.new(nil, nil) { } base.run(iter, 0.0) @items.each do |i| i.run(iter, base.duration) if i.error.nil? puts format("#{i.title}.#{i.op} #{iter} times in %0.3f seconds or %0.3f #{i.op}/sec.", i.duration, iter / i.duration) else puts "***** #{i.title}.#{i.op} failed! #{i.error}" end end summary end def summary width = 6 @items.each do |i| next if i.duration.nil? width = i.title.size if width < i.title.size end iva = @items.clone iva.delete_if { |i| i.duration.nil? } iva = iva.sort_by { |i| i.duration } puts puts 'Summary:' puts format('%*s time (secs) rate (ops/sec)', width, 'System') puts "#{'-' * width} ----------- --------------" iva.each do |i| if i.duration.nil? else puts format('%*s %11.3f %14.3f', width, i.title, i.duration, i.rate) end end puts puts "Comparison Matrix\n(performance factor, 2.0 means row is twice as fast as column)" puts(([' ' * width] + iva.map { |i| format('%*s', width, i.title) }).join(' ')) puts((['-' * width] + iva.map { |i| '-' * width }).join(' ')) iva.each do |i| line = [format('%*s', width, i.title)] iva.each do |o| line << format('%*.2f', width, o.duration / i.duration) end puts line.join(' ') end puts end class Item attr_accessor :title attr_accessor :op attr_accessor :blk attr_accessor :duration attr_accessor :rate attr_accessor :error def initialize(title, op, &blk) @title = title @blk = blk @op = op @duration = nil @rate = nil @error = nil @before = nil end def set_before(&blk) @before = blk end def run(iter, base) GC.start @before.call unless @before.nil? start = Time.now iter.times { @blk.call } @duration = Time.now - start - base @duration = 0.0 if @duration < 0.0 @rate = iter / @duration rescue Exception => e @error = "#{e.class}: #{e.message}" end end # Item end # Perf ox-2.14.17/test/perf_gen.rb000077500000000000000000000077201445411231300154140ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '..' $: << '../lib' $: << '../ext' if __FILE__ == $0 && (i = ARGV.index('-I')) x = ARGV.slice!(i, 2) $: << x[1] end require 'optparse' require 'ox' require 'sample' require 'test/ox/doc' require 'files' require 'perf' begin require 'nokogiri' rescue Exception => e end begin require 'libxml' rescue Exception => e end $verbose = 0 $ox_only = false do_sample = false do_files = false do_load = false do_dump = false do_read = false do_write = false $iter = 1000 opts = OptionParser.new opts.on('-v', 'increase verbosity') { $verbose += 1 } opts.on('-x', 'ox only') { $ox_only = true } opts.on('-s', 'load and dump as sample Ruby object') { do_sample = true } opts.on('-f', 'load and dump as files Ruby object') { do_files = true } opts.on('-l', 'load') { do_load = true } opts.on('-d', 'dump') { do_dump = true } opts.on('-r', 'read') { do_read = true } opts.on('-w', 'write') { do_write = true } opts.on('-a', 'load, dump, read and write') { do_load = true; do_dump = true; do_read = true; do_write = true } opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |it| $iter = it } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } files = opts.parse(ARGV) Ox.default_options = { mode: :generic } data = [] if files.empty? data = [] obj = do_sample ? sample_doc(2) : files('..') xml = Ox.dump(obj, indent: 2, opt_format: true) File.write('sample.xml', xml) gen = Ox.parse(xml) h = { file: 'sample.xml', xml: xml, ox: gen } h[:nokogiri] = Nokogiri::XML::Document.parse(xml) unless defined?(Nokogiri).nil? h[:libxml] = LibXML::XML::Document.string(xml) unless defined?(LibXML).nil? data << h else puts "loading and parsing #{files}\n\n" data = files.map do |f| xml = File.read(f) obj = Ox.parse(xml) gen = Ox.parse(xml) h = { file: f, xml: xml, ox: gen } h[:nokogiri] = Nokogiri::XML::Document.parse(xml) unless defined?(Nokogiri).nil? h[:libxml] = LibXML::XML::Document.string(xml) unless defined?(LibXML).nil? h end end data.each do |d| if do_load perf = Perf.new perf.add('Ox', 'parse') { Ox.parse(xml) } perf.add('Nokogiri', 'parse') { Nokogiri::XML::Document.parse(xml) } unless defined?(Nokogiri).nil? perf.add('LibXML', 'parse') { LibXML::XML::Document.string(xml) } unless defined?(LibXML).nil? perf.run($iter) end if do_dump perf = Perf.new perf.add('Ox', 'dump') { Ox.dump($obj, indent: 2) } perf.before('Ox') { $obj = d[:ox] } unless defined?(Nokogiri).nil? perf.add('Nokogiri', 'dump') { $obj.to_xml(indent: 2) } perf.before('Nokogiri') { $obj = d[:nokogiri] } end unless defined?(LibXML).nil? perf.add('LibXML', 'dump') { $obj.to_s } perf.before('LibXML') { $obj = d[:libxml] } end perf.run($iter) end if do_read $filename = d[:file] perf = Perf.new perf.add('Ox', 'load_file') { Ox.load_file($filename) } perf.add('Nokogiri', 'parse') { Nokogiri::XML::Document.parse(File.open($filename)) } unless defined?(Nokogiri).nil? perf.add('LibXML', 'parse') { LibXML::XML::Document.file($filename) } unless defined?(LibXML).nil? perf.run($iter) end next unless do_write $filename = 'out.xml' perf = Perf.new perf.add('Ox', 'to_file') { Ox.to_file($filename, $obj, indent: 0) } perf.before('Ox') { $obj = d[:ox] } unless defined?(Nokogiri).nil? perf.add('Nokogiri', 'dump') do xml = $obj.to_xml(indent: 0) File.write($filename, xml) end end perf.before('Nokogiri') { $obj = d[:nokogiri] } unless defined?(LibXML).nil? perf.add('LibXML', 'dump') do xml = $obj.to_s File.write($filename, xml) end perf.before('LibXML') { $obj = d[:libxml] } end perf.run($iter) end ox-2.14.17/test/perf_mars.rb000077500000000000000000000052411445411231300156010ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '..' $: << '../lib' $: << '../ext' if __FILE__ == $0 && (i = ARGV.index('-I')) x, path = ARGV.slice!(i, 2) $: << path end require 'optparse' require 'ox' it = 5000 opts = OptionParser.new opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |i| it = i } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } files = opts.parse(ARGV) module Test module Ox class Wrap attr_accessor :values def initialize(v=[]) @values = v end end end end data = { Boolean: Test::Ox::Wrap.new, Fixnum: Test::Ox::Wrap.new, Float: Test::Ox::Wrap.new, String: Test::Ox::Wrap.new, Symbol: Test::Ox::Wrap.new, Time: Test::Ox::Wrap.new, Array: Test::Ox::Wrap.new, Hash: Test::Ox::Wrap.new, Range: Test::Ox::Wrap.new, Regexp: Test::Ox::Wrap.new, Bignum: Test::Ox::Wrap.new, Complex: Test::Ox::Wrap.new, Rational: Test::Ox::Wrap.new, Struct: Test::Ox::Wrap.new, Class: Test::Ox::Wrap.new, Object: Test::Ox::Wrap.new } s = Struct.new('Zoo', :x, :y, :z) (1..200).each do |i| data[:Boolean].values << (0 == (i % 2)) data[:Fixnum].values << ((i - 10) * 101) data[:Float].values << ((i.to_f - 10.7) * 30.5) data[:String].values << "String #{i}" data[:Symbol].values << "Symbol#{i}".to_sym data[:Time].values << (Time.now + i) data[:Array].values << [] data[:Hash].values << {} data[:Range].values << (0..7) data[:Regexp].values << /^[0-9]/ data[:Bignum].values << (7 ** 55) data[:Complex].values << Complex(1, 2) data[:Rational].values << Rational(1, 3) data[:Struct].values << s.new(1, 3, 5) data[:Class].values << Test::Ox::Wrap data[:Object].values << Test::Ox::Wrap.new(i) end puts ' load dump' puts 'type Ox Marshal ratio Ox Marshal ratio' data.each do |type, a| # xml = Ox.dump(a, :indent => -1, :xsd_date => true) xml = Ox.dump(a, indent: -1) # pp a # puts xml start = Time.now (1..it).each do obj = Ox.load(xml, mode: :object) # pp obj end ox_load_time = Time.now - start m = Marshal.dump(a) start = Time.now (1..it).each do obj = Marshal.load(m) end mars_load_time = Time.now - start obj = Ox.load(xml, mode: :object) start = Time.now (1..it).each do xml = Ox.dump(a, indent: -1) end ox_dump_time = Time.now - start start = Time.now (1..it).each do m = Marshal.dump(a) end mars_dump_time = Time.now - start puts format('%8s %6.3f %6.3f %0.1f %6.3f %6.3f %0.1f', type.to_s, ox_load_time, mars_load_time, mars_load_time / ox_load_time, ox_dump_time, mars_dump_time, mars_dump_time / ox_dump_time) end ox-2.14.17/test/perf_obj.rb000077500000000000000000000072071445411231300154150ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '../lib' $: << '../ext' if __FILE__ == $0 && (i = ARGV.index('-I')) x = ARGV.slice!(i, 2) $: << x[1] end require 'optparse' require 'ox' require 'perf' require 'sample' require 'files' begin require 'oj' rescue Exception end $circular = false $indent = 0 ox_only = false do_sample = false do_files = false do_load = false do_dump = false do_read = false do_write = false $iter = 1000 opts = OptionParser.new opts.on('-c', 'circular options') { $circular = true } opts.on('-s', 'load and dump as sample Ruby object') { do_sample = true } opts.on('-f', 'load and dump as files Ruby object') { do_files = true } opts.on('-l', 'load') { do_load = true } opts.on('-d', 'dump') { do_dump = true } opts.on('-r', 'read') { do_read = true } opts.on('-w', 'write') { do_write = true } opts.on('-a', 'load, dump, read and write') { do_load = true; do_dump = true; do_read = true; do_write = true } opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |it| $iter = it } opts.on('-o', 'ox_only') { ox_only = true } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } files = opts.parse(ARGV) $obj = nil $xml = nil $mars = nil $json = nil unless do_load || do_dump || do_read || do_write do_load = true do_dump = true do_read = true do_write = true end # prepare all the formats for input if files.empty? $obj = do_sample ? sample_doc(2) : files('..') $mars = Marshal.dump($obj) $xml = Ox.dump($obj, indent: $indent, circular: $circular) File.write('sample.xml', $xml) File.write('sample.marshal', $mars) unless defined?(Oj).nil? $json = Oj.dump($obj, indent: $indent, circular: $circular) File.write('sample.json', $json) end else puts "loading and parsing #{files}\n\n" files.map do |f| $xml = File.read(f) $obj = Ox.load($xml); $mars = Marshal.dump($obj) $json = Oj.dump($obj, indent: $indent, circular: $circular) unless defined?(Oj).nil? end end Oj.default_options = { mode: :object, indent: $indent } unless defined?(Oj).nil? if do_load puts '-' * 80 puts 'Load Performance' perf = Perf.new perf.add('Ox', 'load') { Ox.load($xml, mode: :object) } perf.add('Oj', 'load') { Oj.load($json) } unless (defined?(Oj).nil? || ox_only) perf.add('Marshal', 'load') { Marshal.load($mars) } unless ox_only perf.run($iter) end if do_dump puts '-' * 80 puts 'Dump Performance' perf = Perf.new perf.add('Ox', 'dump') { Ox.dump($obj, indent: $indent, circular: $circular) } perf.add('Oj', 'dump') { Oj.dump($obj) } unless (defined?(Oj).nil? || ox_only) perf.add('Marshal', 'dump') { Marshal.dump($obj) } unless ox_only perf.run($iter) end if do_read puts '-' * 80 puts 'Read from file Performance' perf = Perf.new perf.add('Ox', 'load_file') { Ox.load_file('sample.xml', mode: :object) } perf.add('Oj', 'load') { Oj.load_file('sample.json') } unless (defined?(Oj).nil? || ox_only) perf.add('Marshal', 'load') { Marshal.load(File.new('sample.marshal')) } unless ox_only perf.run($iter) end if do_write puts '-' * 80 puts 'Write to file Performance' perf = Perf.new perf.add('Ox', 'to_file') { Ox.to_file('sample.xml', $obj, indent: $indent, circular: $circular) } perf.add('Oj', 'to_file') { Oj.to_file('sample.json', $obj) } unless (defined?(Oj).nil? || ox_only) perf.add('Marshal', 'dump') { Marshal.dump($obj, File.new('sample.marshal', 'w')) } unless ox_only perf.run($iter) end ox-2.14.17/test/perf_sax.rb000077500000000000000000000127461445411231300154420ustar00rootroot00000000000000#!/usr/bin/env ruby $: << '.' $: << '..' $: << '../lib' $: << '../ext' if __FILE__ == $0 while (i = ARGV.index('-I')) x = ARGV.slice!(i, 2) $: << x[1] end end require 'optparse' require 'ox' require 'perf' require 'files' begin require 'nokogiri' rescue Exception => e end begin require 'libxml' rescue Exception => e end $verbose = 0 $ox_only = false $all_cbs = false $filename = nil # nil indicates new file names perf.xml will be created and used $filesize = 1000 # KBytes $iter = 1000 $strio = false $pos = false $smart = false opts = OptionParser.new opts.on('-v', 'increase verbosity') { $verbose += 1 } opts.on('-x', 'ox only') { $ox_only = true } opts.on('-a', 'all callbacks') { $all_cbs = true } opts.on('-b', 'html smart') { $smart = true } opts.on('-p', 'update position') { $pos = true; $all_cbs = true } opts.on('-z', 'use StringIO instead of file') { $strio = true } opts.on('-f', '--file [String]', String, 'filename') { |f| $filename = f } opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |it| $iter = it } opts.on('-s', '--size [Int]', Integer, 'file size in KBytes') { |s| $filesize = s } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } opts.parse(ARGV) $xml_str = nil # size is in Kbytes def create_file(filename, size) head = %{ } tail = %{
} row = %{ 1234 A string. This is a longer string that stretches over a larger number of characters. -12.345 2011-09-18 23:07:26 +0900 } cnt = ((size * 1000) - head.size - tail.size) / row.size File.open(filename, 'w') do |f| f.write(head) cnt.times do |i| f.write(format(row, i, i)) end f.write(tail) end end class OxSax < Ox::Sax def error(message, line, column); puts message; end end class OxAllSax < OxSax def start_element(name); end def attr(name, str); end def attr_value(name, value); end def end_element(name); end def text(str); end def value(value); end def instruct(target); end def doctype(value); end def comment(value); end def cdata(value); end end class OxPosAllSax < OxAllSax def initialize @line = nil @column = nil end end unless defined?(Nokogiri).nil? class NoSax < Nokogiri::XML::SAX::Document def error(message); puts message; end def warning(message); puts message; end end class NoAllSax < NoSax def start_element(name, attrs = []); end def characters(text); end def cdata_block(string); end def comment(string); end def end_document(); end def end_element(name); end def start_document(); end def xmldecl(version, encoding, standalone); end end end unless defined?(LibXML).nil? class LxSax include LibXML::XML::SaxParser::Callbacks end class LxAllSax < LxSax def on_start_element(element, attributes); end def on_cdata_block(cdata); end def on_characters(chars); end def on_comment(msg); end def on_end_document(); end def on_end_element(element); end def on_end_element_ns(name, prefix, uri); end def on_error(msg); end def on_external_subset(name, external_id, system_id); end def on_has_external_subset(); end def on_has_internal_subset(); end def on_internal_subset(name, external_id, system_id); end def on_is_standalone(); end def on_processing_instruction(target, data); end def on_reference(name); end def on_start_document(); end def on_start_element_ns(name, attributes, prefix, uri, namespaces); end end end if $filename.nil? create_file('perf.xml', $filesize) $filename = 'perf.xml' end $xml_str = File.read($filename) puts "A #{$filesize} KByte XML file was parsed #{$iter} times for this test." $handler = nil perf = Perf.new perf.add('Ox::Sax', 'sax_parse') do input = $strio ? StringIO.new($xml_str) : IO.open(IO.sysopen($filename)) Ox.sax_parse($handler, input, smart: $smart) input.close end perf.before('Ox::Sax') do $handler = if $all_cbs $pos ? OxPosAllSax.new : OxAllSax.new else OxSax.new end end unless $ox_only unless defined?(Nokogiri).nil? perf.add('Nokogiri::XML::Sax', 'parse') do input = $strio ? StringIO.new($xml_str) : IO.open(IO.sysopen($filename)) $handler.parse(input) input.close end perf.before('Nokogiri::XML::Sax') { $handler = Nokogiri::XML::SAX::Parser.new($all_cbs ? NoAllSax.new : NoSax.new) } end unless defined?(LibXML).nil? perf.add('LibXML::XML::Sax', 'parse') do input = $strio ? StringIO.new($xml_str) : IO.open(IO.sysopen($filename)) parser = LibXML::XML::SaxParser.io(input) parser.callbacks = $handler parser.parse input.close end perf.before('LibXML::XML::Sax') { $handler = $all_cbs ? LxAllSax.new : LxSax.new } end end perf.run($iter) ox-2.14.17/test/sample.rb000077500000000000000000000024031445411231300151010ustar00rootroot00000000000000#!/usr/bin/env ruby -wW2 if $0 == __FILE__ $: << '.' $: << '..' $: << '../lib' $: << '../ext' end require 'sample/doc' def sample_doc(size=3) colors = [:black, :gray, :white, :red, :blue, :yellow, :green, :purple, :orange] d = Sample::Doc.new('Sample') # add some history (0..size * 10).each do |i| d.add_change("Changed at t+#{i}.") end # add some layers (1..size).each do |i| layer = Sample::Layer.new("Layer-#{i}") (1..size).each do |j| g = Sample::Group.new (1..size).each do |k| g2 = Sample::Group.new r = Sample::Rect.new((j * 40) + 10.0, i * 10.0, 10.123456 / k, 10.0 / k, colors[(i + j + k) % colors.size]) r.add_prop(:part_of, layer.name) g2 << r g2 << Sample::Text.new("#{k} in #{j}", r.left, r.top, r.width, r.height) g << g2 end g2 = Sample::Group.new (1..size).each do |k| o = Sample::Oval.new((j * 40) + 12.0, (i * 10.0) + 2.0, 6.0 / k, 6.0 / k, colors[(i + j + k) % colors.size]) o.add_prop(:inside, true) g << o end g << g2 layer << g end d.layers[layer.name] = layer end # some properties d.add_prop(:purpose, 'an example') d end ox-2.14.17/test/sample/000077500000000000000000000000001445411231300145525ustar00rootroot00000000000000ox-2.14.17/test/sample/change.rb000066400000000000000000000004331445411231300163240ustar00rootroot00000000000000module Sample class Change attr_accessor :time attr_accessor :user attr_accessor :comment def initialize(comment=nil, time=nil, user=nil) @user = user || ENV['USER'] @time = time || Time.now @comment = comment end end # Change end # Sample ox-2.14.17/test/sample/dir.rb000066400000000000000000000003171445411231300156560ustar00rootroot00000000000000require 'etc' module Sample class Dir < File attr_accessor :files def initialize(filename) super @files = [] end def <<(f) @files << f end end # Dir end # Sample ox-2.14.17/test/sample/doc.rb000066400000000000000000000013551445411231300156500ustar00rootroot00000000000000require 'sample/hasprops' require 'sample/group' require 'sample/layer' require 'sample/line' require 'sample/shape' require 'sample/oval' require 'sample/rect' require 'sample/text' require 'sample/change' module Sample class Doc include HasProps attr_accessor :title attr_accessor :create_time attr_accessor :user # Hash of layers in the document indexed by layer name. attr_reader :layers attr_reader :change_history def initialize(title) @title = title @user = ENV['USER'] @create_time = Time.now @layers = {} @change_history = [] end def add_change(comment, time=nil, user=nil) @change_history << Change.new(comment, time, user) end end # Doc end # Sample ox-2.14.17/test/sample/file.rb000066400000000000000000000032131445411231300160150ustar00rootroot00000000000000require 'etc' module Sample class File attr_accessor :name, :ctime, :mtime, :size, :owner, :group, :permissions def initialize(filename) @name = ::File.basename(filename) stat = ::File.stat(filename) @ctime = stat.ctime @mtime = stat.mtime @size = stat.size @owner = Etc.getpwuid(stat.uid).name @group = Etc.getgrgid(stat.gid).name if false @permissions = { 'user' => { 'read' => (0 != (stat.mode & 0x0100)), 'write' => (0 != (stat.mode & 0x0080)), 'execute' => (0 != (stat.mode & 0x0040)) }, 'group' => { 'read' => (0 != (stat.mode & 0x0020)), 'write' => (0 != (stat.mode & 0x0010)), 'execute' => (0 != (stat.mode & 0x0008)) }, 'other' => { 'read' => (0 != (stat.mode & 0x0004)), 'write' => (0 != (stat.mode & 0x0002)), 'execute' => (0 != (stat.mode & 0x0001)) } } else @permissions = { 'user' => [0 != (stat.mode & 0x0100) ? 'r' : '-', 0 != (stat.mode & 0x0080) ? 'w' : '-', 0 != (stat.mode & 0x0040) ? 'x' : '-'].join(''), 'group' => [0 != (stat.mode & 0x0020) ? 'r' : '-', 0 != (stat.mode & 0x0010) ? 'w' : '-', 0 != (stat.mode & 0x0008) ? 'x' : '-'].join(''), 'other' => [0 != (stat.mode & 0x0004) ? 'r' : '-', 0 != (stat.mode & 0x0002) ? 'w' : '-', 0 != (stat.mode & 0x0001) ? 'x' : '-'].join('') } end end end # File end # Sample ox-2.14.17/test/sample/group.rb000066400000000000000000000002651445411231300162360ustar00rootroot00000000000000module Sample class Group attr_reader :members def initialize @members = [] end def <<(member) @members << member end end # Group end # Sample ox-2.14.17/test/sample/hasprops.rb000066400000000000000000000004331445411231300167360ustar00rootroot00000000000000module Sample module HasProps def add_prop(key, value) @props = {} unless instance_variable_defined?(:@props) @props[key] = value end def props @props = {} unless instance_variable_defined?(:@props) @props end end # HasProps end # Sample ox-2.14.17/test/sample/layer.rb000066400000000000000000000002321445411231300162100ustar00rootroot00000000000000module Sample class Layer < Group attr_accessor :name def initialize(name) super() @name = name end end # Layer end # Sample ox-2.14.17/test/sample/line.rb000066400000000000000000000004721445411231300160310ustar00rootroot00000000000000module Sample class Line include HasProps attr_accessor :x, :y, :dx, :dy attr_accessor :color attr_accessor :thick def initialize(x, y, dx, dy, thick, color) @x = x @y = y @dx = dx @dy = dy @thick = thick @color = color end end # Line end # Sample ox-2.14.17/test/sample/oval.rb000066400000000000000000000002061445411231300160360ustar00rootroot00000000000000module Sample class Oval < Shape def initialize(left, top, wide, high, color=nil) super end end # Oval end # Sample ox-2.14.17/test/sample/rect.rb000066400000000000000000000002061445411231300160320ustar00rootroot00000000000000module Sample class Rect < Shape def initialize(left, top, wide, high, color=nil) super end end # Rect end # Sample ox-2.14.17/test/sample/shape.rb000066400000000000000000000010561445411231300162010ustar00rootroot00000000000000module Sample class Shape include HasProps attr_accessor :bounds attr_accessor :color attr_accessor :border, :border_color def initialize(left, top, wide, high, color=nil) @bounds = [[left, top], [left + wide, top + high]] @color = color @border = 1 @border_color = :black end def left @bounds[0][0] end def top @bounds[0][1] end def width @bounds[1][0] - @bounds[0][0] end def height @bounds[1][1] - @bounds[0][1] end end # Shape end # Sample ox-2.14.17/test/sample/text.rb000066400000000000000000000006421445411231300160650ustar00rootroot00000000000000module Sample class Text < Shape attr_accessor :text attr_accessor :font attr_accessor :font_size attr_accessor :just attr_accessor :text_color def initialize(text, left, top, wide, high, color=nil) super(left, top, wide, high, color) @text = text @font = 'helvetica' @font_size = 14 @just = 'left' @text_color = 'black' end end # Text end # Sample ox-2.14.17/test/sax/000077500000000000000000000000001445411231300140645ustar00rootroot00000000000000ox-2.14.17/test/sax/basic.xml000066400000000000000000000000071445411231300156640ustar00rootroot00000000000000 ox-2.14.17/test/sax/handlers.rb000066400000000000000000000066551445411231300162250ustar00rootroot00000000000000require 'ox' class StartSax < Ox::Sax attr_accessor :calls def initialize super @calls = [] end def start_element(name) @calls << [:start_element, name] end def attr(name, value) @calls << [:attr, name, value] end end class AllSax < StartSax def initialize super end def instruct(target) @calls << [:instruct, target] end def end_instruct(target) @calls << [:end_instruct, target] end def doctype(value) @calls << [:doctype, value] end def comment(value) @calls << [:comment, value] end def cdata(value) @calls << [:cdata, value] end def text(value) @calls << [:text, value] end def end_element(name) @calls << [:end_element, name] end def error(message, line, column) @calls << [:error, message, line, column] end def abort(name) @calls << [:abort, name] end end class LineColSax < StartSax def initialize @pos = nil # this initializes the @pos variable which will then be set by the parser @line = nil # this initializes the @line variable which will then be set by the parser @column = nil # this initializes the @line variable which will then be set by the parser super end def instruct(target) @calls << [:instruct, target, @pos, @line, @column] end def start_element(name) @calls << [:start_element, name, @pos, @line, @column] end def end_instruct(target) @calls << [:end_instruct, target, @pos, @line, @column] end def doctype(value) @calls << [:doctype, value, @pos, @line, @column] end def comment(value) @calls << [:comment, value, @pos, @line, @column] end def cdata(value) @calls << [:cdata, value, @pos, @line, @column] end def text(value) @calls << [:text, value, @pos, @line, @column] end def end_element(name) @calls << [:end_element, name, @pos, @line, @column] end def attr(name, value) @calls << [:attr, name, value, @pos, @line, @column] end def attrs_done @calls << [:attrs_done, @pos, @line, @column] end def error(message, line, column) @calls << [:error, message, line, column] end end class TypeSax < Ox::Sax attr_accessor :item # method to call on the Ox::Sax::Value Object attr_accessor :type def initialize(type) super() @item = nil @type = type end def attr_value(name, value) @item = value.send(name) end def value(value) @item = value.send(@type) end end class ErrorSax < Ox::Sax attr_reader :errors def initialize super @path = [] @tags = [] @errors = [] end def start_element(tag) @tags << tag @path & @tags end def error(message, line, column) @errors << message end end class HtmlSax < Ox::Sax attr_accessor :calls def initialize super @calls = [] end def start_element(name) @calls << [:start_element, name] end def end_element(name) @calls << [:end_element, name] end def attr(name, value) @calls << [:attr, name, value] end def instruct(target) @calls << [:instruct, target] end def end_instruct(target) @calls << [:end_instruct, target] end def doctype(value) @calls << [:doctype, value] end def comment(value) @calls << [:comment, value] end def cdata(value) @calls << [:cdata, value] end def text(value) @calls << [:text, value] end def error(message, line, column) @calls << [:error, message, line, column] end end ox-2.14.17/test/sax/helpers.rb000066400000000000000000000025561445411231300160630ustar00rootroot00000000000000require 'handlers' module SaxTestHelpers # A helper method to initiate a sax parsing using a specified xml # structure as input, an expected stack of calls, a handler class # and an optional options hash to pass to the parser. # # The options that the parser recognizes are :convert_special and # :smart, which have both boolean values. # # E.g. # parse_compare(%{ This is some text.}, # [[:start_element, :top], # [:text, " This is some text."], # [:end_element, :top] # ], AllSax, :convert_special => true, :smart => true) # def parse_compare(xml, expected, handler_class = AllSax, opts = {}, handler_attr = :calls) handler = handler_class.new input = StringIO.new(xml) options = { symbolize: true, # :convert_special => true, smart: false }.merge(opts) Ox.sax_parse(handler, input, options) actual = handler.send(handler_attr) if expected != actual expected.each_index do |i| puts "#{i}: #{expected[i]} != #{actual[i]}" if expected[i] != actual[i] end end puts "\nexpected: #{expected}\n actual: #{actual}" if expected != actual assert_equal(expected, actual) end # This is needed to stop test/unit from complaining that there is no test # specified. def test_hack assert(true) end end ox-2.14.17/test/sax/sax_check.rb000077500000000000000000000017471445411231300163550ustar00rootroot00000000000000#!/usr/bin/env ruby # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is # required. That can be set in the RUBYOPT environment variable. # export RUBYOPT=-w $VERBOSE = true $: << File.join(File.dirname(__FILE__), '../../lib') $: << File.join(File.dirname(__FILE__), '../../ext') require 'ox' class QuietSax < Ox::Sax def initialize super @line = nil @column = nil end def start_element(name) puts "Start #{name} @ #{@column}" end def end_element(name) puts "End #{name} @ #{@line}:#{@column}" end def attr(name, value); end def instruct(target); end def end_instruct(target); end def doctype(value); end def comment(value); end def cdata(value); end def text(value) puts "text #{value.length} @ #{@line}:#{@column}" end def error(message, line, column) puts "Error: #{message} @ #{line}:#{column}" end end handler = QuietSax.new Ox.sax_parse(handler, ARGF, smart: true) ox-2.14.17/test/sax/sax_test.rb000077500000000000000000001360471445411231300162610ustar00rootroot00000000000000#!/usr/bin/env ruby # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is # required. That can be set in the RUBYOPT environment variable. # export RUBYOPT=-w $VERBOSE = true $: << File.join(File.dirname(__FILE__), '../../lib') $: << File.join(File.dirname(__FILE__), '../../ext') $: << File.join(File.dirname(__FILE__), '.') require 'stringio' require 'bigdecimal' require 'test/unit' require 'optparse' require 'ox' require 'helpers' # require 'smart_test' opts = OptionParser.new opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } opts.parse(ARGV) $ox_sax_options = { encoding: nil, indent: 2, trace: 0, with_dtd: false, with_xml: false, with_instructions: false, circular: false, xsd_date: false, mode: :object, symbolize_keys: true, skip: :skip_return, smart: false, convert_special: true, effort: :strict, invalid_replace: '', strip_namespace: false } class SaxBaseTest < Test::Unit::TestCase include SaxTestHelpers def test_sax_io_pipe Ox.default_options = $ox_sax_options handler = AllSax.new input, w = IO.pipe w << %{} w.close Ox.sax_parse(handler, input) assert_equal([ [:start_element, :top], [:end_element, :top] ], handler.calls) end def test_sax_file Ox.default_options = $ox_sax_options handler = AllSax.new input = File.open(File.join(File.dirname(__FILE__), 'basic.xml')) Ox.sax_parse(handler, input) input.close assert_equal([ [:start_element, :top], [:end_element, :top] ], handler.calls) end def test_sax_file_line_col Ox.default_options = $ox_sax_options handler = LineColSax.new input = File.open(File.join(File.dirname(__FILE__), 'trilevel.xml')) Ox.sax_parse(handler, input) input.close assert_equal([ [:instruct, 'xml', 1, 1, 1], [:attr, :version, '1.0', 15, 1, 15], [:attrs_done, 15, 1, 15], [:end_instruct, 'xml', 20, 1, 20], [:start_element, :top, 23, 2, 1], [:attrs_done, 23, 2, 1], [:start_element, :child, 31, 3, 3], [:attrs_done, 31, 3, 3], [:start_element, :grandchild, 43, 4, 5], [:attrs_done, 43, 4, 5], [:end_element, :grandchild, 55, 4, 17], [:end_element, :child, 59, 5, 3], [:end_element, :top, 68, 6, 1] ], handler.calls) end def test_sax_io_file Ox.default_options = $ox_sax_options handler = AllSax.new input = IO.open(IO.sysopen(File.join(File.dirname(__FILE__), 'basic.xml'))) Ox.sax_parse(handler, input) input.close assert_equal([ [:start_element, :top], [:end_element, :top] ], handler.calls) end def test_sax_instruct_simple Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:instruct, 'xml'], [:end_instruct, 'xml'] ]) end def test_sax_instruct_blank Ox.default_options = $ox_sax_options parse_compare(%{}, [], StartSax) end def test_sax_instruct_attrs Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:attr, :encoding, 'UTF-8'], [:end_instruct, 'xml'] ]) end def test_sax_instruct_noattrs Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:instruct, 'bad'], [:text, 'something'], [:end_instruct, 'bad'] ]) end def test_sax_instruct_loose Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:attr, :encoding, 'UTF-8'], [:end_instruct, 'xml'] ]) end def test_sax_instruct_pi Ox.default_options = $ox_sax_options parse_compare(%{ This is a string. }, [ [:instruct, 'pro'], [:attr, :cat, 'quick'], [:end_instruct, 'pro'], [:start_element, :top], [:start_element, :str], [:text, 'This is a '], [:instruct, 'attrs'], [:attr, :dog, 'big'], [:end_instruct, 'attrs'], [:text, ' string.'], [:end_element, :str], [:instruct, 'content'], [:text, 'dog is big'], [:end_instruct, 'content'], [:end_element, :top] ]) end def test_sax_instruct_no_term Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:instruct, 'xml'], [:error, 'Not Terminated: instruction not terminated', 1, 6], [:end_instruct, 'xml'], [:start_element, :top], [:end_element, :top] ]) end def test_sax_element_simple Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:start_element, :top], [:end_element, :top] ]) end def test_sax_element_attrs Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:start_element, :top], [:attr, :x, '57'], [:attr, :y, '42'], [:error, 'Unexpected Character: attribute value not in quotes', 1, 22], [:attr, :z, '33/'], [:error, "Start End Mismatch: element 'top' not closed", 1, 25], [:end_element, :top] ]) end def test_sax_element_start_end Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:start_element, :top], [:text, ''], [:end_element, :top] ]) end def test_sax_two_top Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:start_element, :top], [:end_element, :top], [:error, 'Out of Order: multiple top level elements', 1, 7], [:start_element, :top], [:end_element, :top] ]) end def test_sax_nested_elements Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:start_element, :top], [:start_element, :child], [:start_element, :grandchild], [:end_element, :grandchild], [:end_element, :child], [:end_element, :top] ]) end def test_sax_elements_case Ox.default_options = $ox_sax_options Ox.default_options = { smart: true, skip: :skip_white } parse_compare(%{ }, [ [:start_element, :top], [:start_element, :Child], [:start_element, :grandchild], [:end_element, :grandchild], [:end_element, :Child], [:end_element, :top] ], AllSax, { smart: true }) end def test_sax_nested1 Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:start_element, :top], [:start_element, :child], [:start_element, :grandchild], [:end_element, :grandchild], [:end_element, :child], [:end_element, :top] ]) end def test_sax_line_col Ox.default_options = $ox_sax_options parse_compare(%{ Some text. }, [ [:instruct, 'xml', 1, 1, 1], [:attr, :version, '1.0', 15, 1, 15], [:attrs_done, 15, 1, 15], [:end_instruct, 'xml', 20, 1, 20], [:doctype, ' top PUBLIC "top.dtd"', 23, 2, 1], [:start_element, :top, 55, 3, 1], [:attr, :attr, 'one', 65, 3, 11], [:attrs_done, 65, 3, 11], [:comment, ' family ', 74, 4, 3], [:start_element, :child, 92, 5, 3], [:attrs_done, 92, 5, 3], [:start_element, :grandchild, 104, 6, 5], [:attrs_done, 104, 6, 5], [:end_element, :grandchild, 116, 6, 17], [:cdata, 'see data.', 122, 7, 5], [:end_element, :child, 146, 8, 3], [:text, "Some text.\n", 154, 8, 10], [:end_element, :top, 165, 9, 1], [:error, 'Out of Order: multiple top level elements', 10, 1], [:start_element, :second, 172, 10, 1], [:attrs_done, 172, 10, 1], [:start_element, :inside, 183, 11, 3], [:attrs_done, 183, 11, 3], [:end_element, :inside, 191, 11, 11], [:end_element, :second, 193, 12, 1] ], LineColSax) end def test_sax_element_name_mismatch Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:start_element, :top], [:start_element, :child], [:start_element, :grandchild], [:end_element, :grandchild], [:error, "Start End Mismatch: element 'parent' closed but not opened", 5, 3], [:start_element, :parent], [:end_element, :parent], [:error, "Start End Mismatch: element 'top' close does not match 'child' open", 6, 1], [:end_element, :child], [:end_element, :top] ]) end def test_sax_nested Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:start_element, :top], [:start_element, :child], [:start_element, :grandchild], [:end_element, :grandchild], [:end_element, :child], [:start_element, :child], [:start_element, :grandchild], [:end_element, :grandchild], [:start_element, :grandchild], [:end_element, :grandchild], [:end_element, :child], [:end_element, :top] ]) end def test_sax_element_no_term Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:start_element, :top], [:start_element, :child], [:end_element, :child], [:error, "Start End Mismatch: element 'top' not closed", 4, 0], [:end_element, :top] ]) end def test_sax_text Ox.default_options = $ox_sax_options parse_compare(%{This is some text.}, [ [:start_element, :top], [:text, 'This is some text.'], [:end_element, :top] ]) end def test_sax_open_close_element Ox.default_options = $ox_sax_options parse_compare(%{}, [ [:start_element, :top], [:start_element, :mid], [:text, ''], [:end_element, :mid], [:end_element, :top] ]) end def test_sax_empty_element Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:start_element, :top], [:text, ' '], [:end_element, :top] ], AllSax, { skip: :skip_white }) end def test_sax_empty_element_name Ox.default_options = $ox_sax_options parse_compare(%{ <> zzz }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:start_element, :top], [:error, 'Invalid Format: empty element', 3, 3], [:start_element, :abc], [:attr, :x, '1'], [:text, 'zzz'], [:end_element, :abc], [:end_element, :top] ]) end def test_sax_empty_element_noskip Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:text, ' '], [:start_element, :top], [:text, ' '], [:end_element, :top] ], AllSax, { skip: :skip_none }) end def test_sax_special Ox.default_options = $ox_sax_options parse_compare(%{This is <some> π text.}, [ [:start_element, :top], [:attr, :name, 'A&Z'], [:text, "This is \u03c0 text."], [:end_element, :top] ], AllSax, convert_special: true) end def test_sax_bad_special Ox.default_options = $ox_sax_options parse_compare(%{&example;}, [ [:start_element, :top], [:error, 'Invalid Format: Invalid special character sequence', 1, 11], [:attr, :name, '&example;'], [:error, 'Invalid Format: Invalid special character sequence', 1, 22], [:text, '&example;'], [:end_element, :top] ], AllSax, convert_special: true) end def test_sax_ignore_special Ox.default_options = $ox_sax_options parse_compare(%{&example;}, [ [:start_element, :top], [:attr, :name, '&example;'], [:text, '&example;'], [:end_element, :top] ], AllSax, convert_special: false) end def test_sax_not_special Ox.default_options = $ox_sax_options parse_compare(%{This is <some> text.}, [ [:start_element, :top], [:attr, :name, 'A&Z'], [:text, 'This is <some> text.'], [:end_element, :top] ], AllSax, convert_special: false) end def test_sax_special_default Ox.default_options = $ox_sax_options orig = Ox.default_options[:convert_special] Ox.default_options = { convert_special: true } parse_compare(%{This is <some> text.}, [ [:start_element, :top], [:attr, :name, 'A&Z'], [:text, 'This is text.'], [:end_element, :top] ], AllSax) Ox.default_options = { convert_special: orig } end def test_sax_not_special_default Ox.default_options = $ox_sax_options orig = Ox.default_options[:convert_special] Ox.default_options = { convert_special: false } parse_compare(%{This is <some> text.}, [ [:start_element, :top], [:attr, :name, 'A&Z'], [:text, 'This is <some> text.'], [:end_element, :top] ], AllSax) Ox.default_options = { convert_special: orig } end def test_sax_whitespace Ox.default_options = $ox_sax_options parse_compare(%{ This is some text.}, [ [:start_element, :top], [:text, ' This is some text.'], [:end_element, :top] ]) end def test_sax_text_no_term Ox.default_options = $ox_sax_options parse_compare(%{This is some text.}, [ [:start_element, :top], [:error, 'Not Terminated: text not terminated', 1, 23], [:text, 'This is some text.'], [:error, "Start End Mismatch: element 'top' not closed", 1, 23], [:end_element, :top] ]) end # TBD invalid chacters in text def test_sax_doctype Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:doctype, ' top PUBLIC "top.dtd"'], [:start_element, :top], [:end_element, :top] ]) end def test_sax_doctype_big Ox.default_options = $ox_sax_options parse_compare(%{ ]> }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:doctype, %{ Objects []}], [:start_element, :top], [:end_element, :top] ]) end def test_sax_doctype_bad_order Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:start_element, :top], [:end_element, :top], [:error, 'Out of Order: DOCTYPE can not come after an element', 3, 10], [:doctype, ' top PUBLIC "top.dtd"'] ]) end def test_sax_doctype_space Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:error, 'Unexpected Character: }, [ [:start_element, :top], [:error, 'Unexpected Character: DOCTYPE, CDATA, or comment expected', 2, 6], [:end_element, :top] ]) end def test_sax_comment_simple Ox.default_options = $ox_sax_options parse_compare(%{ }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:comment, 'First comment.'] ]) end def test_sax_comment Ox.default_options = $ox_sax_options parse_compare(%{ BeforeAfter }, [ [:instruct, 'xml'], [:attr, :version, '1.0'], [:end_instruct, 'xml'], [:comment, 'First comment.'], [:start_element, :top], [:text, 'Before'], [:comment, 'Nested comment.'], [:text, 'After'], [:end_element, :top] ]) end def test_sax_comment_no_term Ox.default_options = $ox_sax_options parse_compare(%{ one', overlay: overlay) assert_equal([ [:start_element, :html], [:start_element, :h1], [:text, 'title'], [:end_element, :h1], [:end_element, :html] ], handler.calls) end def test_sax_html_off Ox.default_options = $ox_sax_options handler = AllSax.new overlay = Ox.sax_html_overlay overlay['table'] = :off overlay['td'] = :off overlay['!--'] = :off Ox.sax_html(handler, '

title


one
', overlay: overlay) assert_equal([ [:start_element, :html], [:start_element, :h1], [:text, 'title'], [:end_element, :h1], [:start_element, :hr], [:end_element, :hr], [:start_element, :tr], [:end_element, :tr], [:end_element, :html] ], handler.calls) end def test_sax_html_inactive_full_map Ox.default_options = $ox_sax_options handler = AllSax.new overlay = Ox.sax_html_overlay overlay['table'] = :inactive overlay['td'] = :inactive Ox.sax_html(handler, '

title

one
', overlay: overlay) assert_equal([ [:start_element, :html], [:start_element, :h1], [:text, 'title'], [:end_element, :h1], [:comment, 'comment'], [:start_element, :tr], [:text, 'one'], [:end_element, :tr], [:end_element, :html] ], handler.calls) end def test_sax_html_abort Ox.default_options = $ox_sax_options handler = AllSax.new overlay = Ox.sax_html_overlay overlay['table'] = :abort Ox.sax_html(handler, '

title

one
', overlay: overlay) assert_equal([ [:start_element, :html], [:start_element, :h1], [:text, 'title'], [:end_element, :h1], [:abort, :table] ], handler.calls) end def test_sax_html_attr Ox.default_options = $ox_sax_options handler = AllSax.new overlay = Ox.sax_html_overlay html = %{ } Ox.sax_html(handler, html, overlay: overlay, skip: :skip_white) assert_equal([ [:doctype, ' HTML'], [:start_element, :html], [:attr, :lang, 'en'], [:start_element, :head], [:attr, :url, "http://ohler.com?x=2"], [:text, " "], [:end_element, :head], [:end_element, :html], ], handler.calls) end end ox-2.14.17/test/sax/smart_test.rb000077500000000000000000000542241445411231300166100ustar00rootroot00000000000000#!/usr/bin/env ruby # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is # required. That can be set in the RUBYOPT environment variable. # export RUBYOPT=-w $VERBOSE = true $: << File.join(File.dirname(__FILE__), '../../lib') $: << File.join(File.dirname(__FILE__), '../../ext') $: << File.join(File.dirname(__FILE__), '.') require 'stringio' require 'test/unit' require 'optparse' require 'helpers' require 'ox' opts = OptionParser.new opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } opts.parse(ARGV) class SaxSmartTest < Test::Unit::TestCase include SaxTestHelpers NORMALELEMENTS = { 'a' => {}, 'abbr' => {}, 'address' => {}, 'article' => {}, 'aside' => {}, 'audio' => {}, 'b' => {}, 'bdi' => {}, 'bdo' => {}, 'blockquote' => {}, 'body' => { 'parents' => ['html'] }, 'button' => {}, 'canvas' => {}, 'caption' => { 'parents' => ['table'] }, 'cite' => {}, 'colgroup' => { 'parents' => ['table'], 'childs' => ['col'] }, 'data' => {}, 'datalist' => { 'childs' => ['option'] }, 'dl' => { 'childs' => ['dt', 'dd'] }, 'dt' => { 'parents' => ['dl'] }, 'dd' => { 'parents' => ['dl'] }, 'del' => {}, 'details' => { 'childs' => ['summary'] }, 'dfn' => {}, 'div' => {}, 'em' => {}, 'fieldset' => {}, 'figcaption' => {}, 'figure' => {}, 'footer' => {}, 'form' => {}, 'h1' => {}, 'h2' => {}, 'h3' => {}, 'h4' => {}, 'h5' => {}, 'h6' => {}, 'head' => { 'parents' => ['html'] }, 'hgroup' => { 'childs' => ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] }, 'html' => { 'childs' => ['head', 'body'] }, 'i' => {}, 'iframe' => {}, 'ins' => {}, 'kdb' => {}, 'label' => {}, 'legend' => { 'parents' => ['fieldset'] }, 'li' => { 'parents' => ['ul', 'ol', 'menu'] }, 'map' => {}, 'mark' => {}, 'menu' => { 'childs' => ['li'] }, 'meter' => {}, 'nav' => {}, 'noscript' => {}, 'object' => { 'childs' => ['param'] }, 'ol' => { 'childs' => ['li'] }, 'optgroup' => { 'parents' => ['select'], 'childs' => ['option'] }, 'option' => { 'parents' => ['optgroup', 'select', 'datalist'] }, 'output' => {}, 'p' => {}, 'pre' => {}, 'progress' => {}, 'q' => {}, 'rp' => { 'parents' => ['ruby'] }, 'rt' => { 'parents' => ['ruby'] }, 'ruby' => { 'childs' => ['rt', 'rp'] }, 's' => {}, 'samp' => {}, 'script' => {}, 'section' => {}, 'select' => { 'childs' => ['option', 'optgroup'] }, 'small' => {}, 'span' => {}, 'strong' => {}, 'style' => {}, 'sub' => {}, 'summary' => { 'parents' => ['details'] }, 'sup' => {}, 'table' => { 'childs' => ['caption', 'colgroup', 'thead', 'tbody', 'tfoot', 'tr'] }, 'tbody' => { 'childs' => ['tr'], 'parents' => ['table'] }, 'td' => { 'parents' => ['tr'] }, 'textarea' => {}, 'tfoot' => { 'parents' => ['table'], 'childs' => ['tr'] }, 'th' => { 'parents' => ['tr'] }, 'thead' => { 'childs' => ['tr'], 'parents' => ['table'] }, 'time' => {}, 'title' => { 'parents' => ['head'] }, 'tr' => { 'parents' => ['table', 'thead', 'tbody', 'tfoot'], 'childs' => ['td', 'th'] }, 'u' => {}, 'ul' => { 'childs' => ['li'] }, 'var' => {}, 'video' => {} } VOIDELEMENTS = { 'area' => { 'parents' => ['map'] }, 'base' => { 'parents' => ['head'] }, 'br' => {}, 'col' => { 'parents' => ['colgroup'] }, 'command' => { 'parents' => ['colgroup'] }, 'embed' => {}, 'hr' => {}, 'img' => {}, 'input' => {}, 'keygen' => {}, 'link' => {}, 'meta' => { 'parents' => ['head'] }, 'param' => { 'parents' => ['object'] }, 'source' => { 'parents' => ['audio', 'video'] }, 'track' => { 'parents' => ['audio', 'video'] }, 'wbr' => {} } # Make the :smart => true option the default one def smart_parse_compare(xml, expected, handler = AllSax, opts = {}, handler_attr = :calls) parse_compare(xml, expected, handler, opts.merge(smart: true, skip: :skip_white), handler_attr) end end class ErrorsOnParentNormalElementTest < SaxSmartTest attr_reader :w def initialize(*args) @w = lambda { |s, ws| "<#{ws}>" + s + "" } super(*args) end def parents_of(el) return [] if el == 'html' NORMALELEMENTS[el]['parents'] || ['body'] end def ancestry_of(el, parent = nil) p = parent || parents_of(el)[0] [el] + (p ? ancestry_of(p) : []) end def ancestries(el) parents_of(el).map { |p| ancestry_of(el, p) } end def test_no_error_in_dependent_parent_elements NORMALELEMENTS.each_key do |el| ancestries(el).each do |arr| html = arr.reduce(&w) smart_parse_compare(html, [], ErrorSax, {}, :errors) end end end end class ErrorsOnParentVoidElementTest < SaxSmartTest def construct_html(el) s = '' str = (VOIDELEMENTS[el]['parents'] || []).each do |p| s += "<#{p}><#{el}>" end "#{str}" end def test_no_error_in_dependent_parent_on_void_elements VOIDELEMENTS.each_key do |el| smart_parse_compare(construct_html(el), [], ErrorSax, {}, :errors) end end end ## # A class that groups tests concerning DOCTYPE of an html document. # More info: http://www.w3.org/TR/html5/syntax.html#the-doctype ## class SaxSmartDoctypeTest < SaxSmartTest def test_doctype_html5 html = %{} smart_parse_compare(html, [[:doctype, ' HTML']]) end def test_doctype_html401_strict html = %{} smart_parse_compare(html, [[:doctype, ' HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"']]) end def test_doctype_html401_transitional html = %{} smart_parse_compare(html, [[:doctype, ' HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"']]) end def test_doctype_html401_frameset html = %{} smart_parse_compare(html, [[:doctype, ' HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"']]) end def test_doctype_xhtml_10_transitional html = %{} smart_parse_compare(html, [[:doctype, ' html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"']]) end def test_doctype_xhtml_10_strict html = %{} smart_parse_compare(html, [[:doctype, ' html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"']]) end def test_doctype_xhtml_10_frameset html = %{} smart_parse_compare(html, [[:doctype, ' html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"']]) end def test_doctype_xhtml_11 html = %{} smart_parse_compare(html, [[:doctype, ' html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"']]) end def test_doctype_declaration_allcaps # allcaps is only required when not smart html = %{} parse_compare(html, [[:error, 'Case Error: expected DOCTYPE all in caps', 1, 10], [:doctype, ' HTML']], AllSax) end end ## # A class that groups tests concerning the normal elements of an html document. # More info: http://www.w3.org/TR/html5/syntax.html#normal-elements ## class SaxSmartNormalTagTest < SaxSmartTest def test_normal_tags html = %{A terminated text} smart_parse_compare(html, [[:start_element, :html], [:attr, :class, 'class1'], [:text, 'A terminated text'], [:end_element, :html]]) end def test_empty_element html = %{<>A terminated text} smart_parse_compare(html, [[:start_element, :html], [:attr, :class, 'class1'], [:error, 'Invalid Format: empty element', 1, 22], [:text, 'A terminated text'], [:end_element, :html]]) end def test_normal_self_closing_tags html = %{
} smart_parse_compare(html, [[:start_element, :br], [:end_element, :br]]) end def test_with_no_close html = %{} smart_parse_compare(html, [[:start_element, :html], [:error, "Start End Mismatch: element 'html' not closed", 1, 6], [:end_element, :html]]) end def test_with_no_close_and_not_terminated_text html = %{A not terminated text} smart_parse_compare(html, [[:start_element, :html], [:error, 'Not Terminated: text not terminated', 1, 27], [:text, 'A not terminated text'], [:error, "Start End Mismatch: element 'html' not closed", 1, 27], [:end_element, :html]]) end def test_with_no_close_nested html = %{Test
A div element} smart_parse_compare(html, [[:start_element, :html], [:text, 'Test '], [:start_element, :div], [:attr, :style, 'width: 100px;'], [:text, 'A div element'], [:error, "Start End Mismatch: element 'html' close does not match 'div' open", 1, 52], [:end_element, :div], [:end_element, :html]]) end def test_with_no_close_with_nested html = %{
A div element
} smart_parse_compare(html, [[:start_element, :html], [:start_element, :div], [:attr, :class, 'test'], [:text, 'A div element'], [:end_element, :div], [:error, "Start End Mismatch: element 'html' not closed", 1, 43], [:end_element, :html]]) end def test_with_no_close_and_not_terminated_text_with_nested html = %{A not terminated
A div
text} smart_parse_compare(html, [[:start_element, :html], [:text, 'A not terminated '], [:start_element, :div], [:text, 'A div'], [:end_element, :div], [:error, 'Not Terminated: text not terminated', 1, 44], [:text, ' text'], [:error, "Start End Mismatch: element 'html' not closed", 1, 44], [:end_element, :html]]) end def test_invalid_element_name html = %{ Hello } smart_parse_compare(html, [[:start_element, :html], [:error, 'Invalid Element: budy is not a valid element type for a HTML document type.', 3, 8], [:start_element, :budy], [:text, 'Hello'], [:end_element, :budy], [:end_element, :html]]) end def test_comment_active html = %{

hello

} overlay = Ox.sax_html_overlay.dup overlay.each_key {|k| overlay[k] = :off } overlay['!--'] = :active handler = AllSax.new input = StringIO.new(html) options = { overlay: overlay, skip: :skip_white } Ox.sax_html(handler, input, options) expected = [[:comment, ' a comment ']] actual = handler.calls puts "\nexpected: #{expected}\n actual: #{actual}" if expected != actual assert_equal(expected, actual) end def test_nested html = %{
Word
} smart_parse_compare(html, [[:start_element, :html], [:start_element, :body]] + ([[:start_element, :div]] * 20) + [[:text, ' Word ']] + ([[:end_element, :div]] * 20) + [[:end_element, :body], [:end_element, :html]]) end # The expected behaviour is to trigger an error and then trigger the start / end events # which is not the case for void elements, where only an error is triggered. def test_not_opened html = '
' smart_parse_compare(html, [[:error, "Start End Mismatch: element 'div' closed but not opened", 1, 1], [:start_element, :div], [:end_element, :div]]) end def test_not_opened_nested html = '

A header here

' smart_parse_compare(html, [[:start_element, :h1], [:error, 'Unexpected Character: attribute value not in quotes', 1, 11], [:attr, :class, 'a_class'], [:text, 'A header'], [:error, "Start End Mismatch: element 'div' closed but not opened", 1, 27], [:start_element, :div], [:end_element, :div], [:text, ' here'], [:end_element, :h1]]) end def test_unquoted_slash html = '
def' smart_parse_compare(html, [[:start_element, :a], [:error, 'Unexpected Character: attribute value not in quotes', 1, 9], [:attr, :href, 'abc/'], [:text, 'def'], [:end_element, :a]]) end def test_unquoted_slash_no_close html = 'def' smart_parse_compare(html, [[:start_element, :a], [:error, 'Unexpected Character: attribute value not in quotes', 1, 9], [:attr, :href, 'abc/'], [:error, 'Not Terminated: text not terminated', 1, 16], [:text, 'def'], [:error, "Start End Mismatch: element 'a' not closed", 1, 16], [:end_element, :a]]) end end ## # A class that groups tests concerning the so called void elements of an html document. # More info: http://www.w3.org/TR/html5/syntax.html#void-elements ## # class SaxSmartVoidTagTest < SaxSmartTest # # VOIDELEMENTS = [ # #"area", # only in map # #"base", # only in head # "br", # #"col", # only in colgroup # #"command", # not a void tag # "embed", # "hr", # "img", # "input", # "keygen", # #"link", # only in head # #"meta", # only in head # "param", # #"source", # only in media (audio, video) # #"track", # only in media (audio, video) # "wbr" # ] # # def test_closed # VOIDELEMENTS.each do |el| # html = %{A terminated <#{el}/> text} # smart_parse_compare(html, # [ # [:start_element, :html], # [:text, "A terminated "], # [:start_element, el.to_sym], # [:end_element, el.to_sym], # [:text, " text"], # [:end_element, :html] # ]) # end # end # # def test_not_closed # VOIDELEMENTS.each do |el| # html = %{A terminated <#{el}> text} # smart_parse_compare(html, # [ # [:start_element, :html], # [:text, "A terminated "], # [:start_element, el.to_sym], # [:end_element, el.to_sym], # [:text, " text"], # [:end_element, :html] # ]) # end # end # # # Fix this error to be supported # def test_invalid_syntax # VOIDELEMENTS.each do |el| # html = %{A terminated <#{el}>nice\n text} # smart_parse_compare(html, # [ # [:start_element, :html], # [:text, "A terminated "], # [:start_element, el.to_sym], # [:end_element, el.to_sym], # [:text, "nice\n"], # [:error, "Start End Mismatch: element '#{el}' should not have a separate close element", 2, 1], # [:text, " text"], # [:end_element, :html] # ]) # end # end # # end ## # A class that groups tests concerning the table element. Because this element # assumes a specific nested structure its testing must be made seperately from # the normal tags testing. ## class SaxSmartTableTagTest < SaxSmartTest def test_html_table html = %{ Table
onetwo
badbad2
} smart_parse_compare(html, [[:start_element, :html], [:start_element, :body], [:text, 'Table '], [:start_element, :table], [:start_element, :tr], [:start_element, :td], [:text, 'one'], [:end_element, :td], [:start_element, :td], [:text, 'two'], [:end_element, :td], [:end_element, :tr], [:start_element, :tr], [:start_element, :td], [:text, 'bad'], [:error, 'Invalid Element: td can not be nested in a HTML document, closing previous.', 6, 21], [:end_element, :td], [:start_element, :td], [:text, 'bad2'], [:error, "Start End Mismatch: element 'tr' close does not match 'td' open", 6, 26], [:end_element, :td], [:end_element, :tr], [:end_element, :table], [:end_element, :body], [:end_element, :html]]) end def test_html_bad_table html = %{
one
} smart_parse_compare(html, [[:start_element, :html], [:start_element, :body], [:start_element, :table], [:start_element, :div], [:error, 'Invalid Element: tr can not be a child of a div in a HTML document.', 6, 12], [:start_element, :tr], [:start_element, :td], [:text, 'one'], [:end_element, :td], [:end_element, :tr], [:end_element, :div], [:end_element, :table], [:end_element, :body], [:end_element, :html]]) end def html_parse_compare(xml, expected, opts = {}) handler = AllSax.new input = StringIO.new(xml) options = { symbolize: true, smart: false, skip: :skip_white }.merge(opts) Ox.sax_html(handler, input, options) actual = handler.send(:calls) puts "\nexpected: #{expected}\n actual: #{actual}" if expected != actual assert_equal(expected, actual) end def test_nest_ok html = %{ Table
onetwo
} hints = Ox.sax_html_overlay hints['td'] = :nest_ok html_parse_compare(html, [[:start_element, :html], [:start_element, :body], [:text, 'Table '], [:start_element, :table], [:start_element, :tr], [:start_element, :td], [:text, 'one'], [:start_element, :td], [:text, 'two'], [:end_element, :td], [:end_element, :td], [:end_element, :tr], [:end_element, :table], [:end_element, :body], [:end_element, :html]], { overlay: hints }) end def test_nest_ok_auto_closing html = %{
test} hints = Ox.sax_html_overlay hints['h5'] = :nest_ok html_parse_compare(html, [[:start_element, :html], [:start_element, :body], [:start_element, :h5], [:text, 'test'], [:error, "Start End Mismatch: element 'body' close does not match 'h5' open", 1, 21], [:end_element, :h5], [:end_element, :body], [:end_element, :html]], { overlay: hints }) end end ox-2.14.17/test/sax/trilevel.xml000066400000000000000000000001121445411231300164260ustar00rootroot00000000000000 ox-2.14.17/test/tests.rb000077500000000000000000001513271445411231300147740ustar00rootroot00000000000000#!/usr/bin/env ruby # Ubuntu does not accept arguments to ruby when called using env. To get warnings to show up the -w options is # required. That can be set in the RUBYOPT environment variable. # export RUBYOPT=-w $VERBOSE = true $: << File.join(File.dirname(__FILE__), '../lib') $: << File.join(File.dirname(__FILE__), '../ext') require 'rubygems' if RUBY_VERSION.start_with?('1.8.') require 'test/unit' require 'date' require 'bigdecimal' require 'ox' $ruby = RUBY_DESCRIPTION.split(' ')[0] $ruby = 'ree' if 'ruby' == $ruby && RUBY_DESCRIPTION.include?('Ruby Enterprise Edition') $indent = 2 $ox_object_options = { encoding: nil, margin: '', indent: 2, trace: 0, with_dtd: false, with_xml: false, with_instructions: false, circular: false, xsd_date: false, mode: :object, symbolize_keys: true, element_key_mod: nil, attr_key_mod: nil, skip: :skip_white, smart: false, convert_special: true, effort: :strict, no_empty: false, with_cdata: false, invalid_replace: '', strip_namespace: false, overlay: nil } $ox_generic_options = { encoding: nil, margin: '', indent: 2, trace: 0, with_dtd: false, with_xml: false, with_instructions: false, circular: false, xsd_date: false, mode: :generic, symbolize_keys: true, element_key_mod: nil, attr_key_mod: nil, skip: :skip_white, smart: false, convert_special: true, effort: :strict, no_empty: false, with_cdata: false, invalid_replace: '', strip_namespace: false, overlay: nil } class Func < Test::Unit::TestCase alias assert_raise assert_raises unless respond_to?(:assert_raise) def test_get_options Ox.default_options = $ox_object_options opts = Ox.default_options assert_equal($ox_object_options, opts) end def test_set_options Ox.default_options = $ox_object_options o2 = { encoding: 'UTF-8', margin: 'zz', indent: 4, trace: 1, with_dtd: true, with_xml: false, with_instructions: true, circular: true, xsd_date: true, mode: :object, symbolize_keys: true, element_key_mod: nil, attr_key_mod: nil, skip: :skip_return, smart: true, convert_special: false, effort: :tolerant, no_empty: true, with_cdata: true, invalid_replace: '*', strip_namespace: 'spaced', overlay: nil } o3 = { xsd_date: false } Ox.default_options = o2 opts = Ox.default_options assert_equal(o2, opts); Ox.default_options = o3 # see if it throws an exception Ox.default_options = $ox_object_options end def test_nil Ox.default_options = $ox_object_options dump_and_load(nil, false) end def test_true Ox.default_options = $ox_object_options dump_and_load(true, false) end def test_false Ox.default_options = $ox_object_options dump_and_load(false, false) end def test_fixnum Ox.default_options = $ox_object_options dump_and_load(7, false) dump_and_load(-19, false) dump_and_load(0, false) end def test_float Ox.default_options = $ox_object_options dump_and_load(7.7, false) dump_and_load(-1.9, false) dump_and_load(0.0, false) dump_and_load(-10.000005, false) dump_and_load(1.000000000005, false) end def test_string Ox.default_options = $ox_object_options dump_and_load('a string', false) dump_and_load('', false) end def test_symbol Ox.default_options = $ox_object_options dump_and_load(:a_symbol, false) dump_and_load(:<=, false) end def test_base64 Ox.default_options = $ox_object_options dump_and_load('a & x', false) end def test_time Ox.default_options = $ox_object_options t = Time.local(2012, 1, 5, 23, 58, 7) dump_and_load(t, false) end def test_date Ox.default_options = $ox_object_options dump_and_load(Date.new(2011, 1, 5), false) end def test_array Ox.default_options = $ox_object_options dump_and_load([], false) dump_and_load([1, 'a'], false) end def test_hash Ox.default_options = $ox_object_options dump_and_load({}, false) dump_and_load({ 'a' => 1, 2 => 'b' }, false) end def test_range Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load((0..3), false) dump_and_load((-2..3.7), false) dump_and_load(('a'...'f'), false) t = Time.local(2012, 1, 5, 23, 58, 7) t2 = t + 20 dump_and_load((t..t2), false) end end def test_regex Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby assert(true) else dump_and_load(/^[0-9]/ix, false) dump_and_load(/^[&0-9]/ix, false) # with xml-unfriendly character end end def test_bignum Ox.default_options = $ox_object_options dump_and_load(7 ** 55, false) dump_and_load(-7 ** 55, false) end def test_bigdecimal Ox.default_options = $ox_object_options bd = BigDecimal('7.123456789') dump_and_load(bd, false) end def test_complex_number Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby assert(true) else dump_and_load(Complex(1), false) dump_and_load(Complex(3, 2), false) end end def test_rational Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') assert(true) else dump_and_load(Rational(1, 3), false) dump_and_load(Rational(0, 3), false) end end def test_object Ox.default_options = $ox_object_options dump_and_load(Bag.new({}), false) dump_and_load(Bag.new(:@x => 3), false) end def test_bad_object Ox.default_options = $ox_object_options xml = %{ 3 } xml2 = %{ 7 } assert_raise(NameError) do Ox.load(xml, mode: :object, trace: 0) end loaded = Ox.load(xml, mode: :object, trace: 0, effort: :tolerant) assert_nil(loaded) loaded = Ox.load(xml, mode: :object, trace: 0, effort: :auto_define) assert_equal(loaded.class.to_s, 'Bad::Boy') assert_equal(loaded.class.superclass.to_s, 'Ox::Bag') loaded = Ox.load(xml2, mode: :object, trace: 0, effort: :auto_define) assert_equal(loaded.class.to_s, 'Bad') assert_equal(loaded.class.superclass.to_s, 'Ox::Bag') end def test_bad_class Ox.default_options = $ox_object_options xml = %{ 3 } assert_raise(Ox::ParseError) do Ox.load(xml, mode: :object, trace: 0) end end def test_empty_element Ox.default_options = $ox_object_options xml = %{ <> } assert_raise(Ox::ParseError) do Ox.load(xml, mode: :object, trace: 0) end end def test_xml_instruction_format Ox.default_options = $ox_object_options xml = %{ Test } loaded = Ox.load(xml, mode: :object) assert_equal('Test', loaded); end def test_dump_invalid_character assert_raise(Ox::SyntaxError) { Ox.dump("foo\x19bar") } end def test_unsupported_ox_version assert_raise(Ox::SyntaxError) { Ox.parse(%{foobar})} end def test_prolog_syntax_error xml = %{Test} assert_raise(Ox::SyntaxError) { Ox.parse(xml) } end def test_xml_instruction Ox.default_options = $ox_object_options xml = Ox.dump('test', mode: :object, with_xml: false) assert_equal("test\n", xml) xml = Ox.dump('test', mode: :object, with_xml: true) assert_equal("\ntest\n", xml) xml = Ox.dump('test', mode: :object, with_xml: true, encoding: 'UTF-8') assert_equal("\ntest\n", xml) end def test_ox_instruction Ox.default_options = $ox_object_options xml = Ox.dump('test', mode: :object, with_xml: true, with_instructions: true) assert_equal("\n\ntest\n", xml) xml = Ox.dump('test', mode: :object, with_instructions: true) assert_equal("\ntest\n", xml) xml = Ox.dump('test', mode: :object, with_instructions: true, circular: true, xsd_date: true) assert_equal("\ntest\n", xml) xml = Ox.dump('test', mode: :object, with_instructions: true, circular: false, xsd_date: false) assert_equal("\ntest\n", xml) end def test_embedded_instruction Ox.default_options = $ox_object_options xml = %{ This is a string. } doc = Ox.load(xml, mode: :generic) inst = doc.top.str.nodes[1] assert_equal(Ox::Instruct, inst.class) assert_equal('attrs', inst.target) assert_nil(inst.content) assert_equal({ dog: 'big' }, inst.attributes) inst = doc.top.content assert_equal(Ox::Instruct, inst.class) assert_equal('content', inst.target) assert_equal(' dog is big', inst.content) assert_equal({}, inst.attributes) x = Ox.dump(doc, with_xml: true) assert_equal(xml, x) end def test_big_instruction Ox.default_options = $ox_object_options xml = %{ This is a an MML instruction over 256 bytes. &sgr; v 10 26 ?> } doc = Ox.load(xml, mode: :generic) inst = doc.top.nodes[1] assert_equal(Ox::Instruct, inst.class) assert_equal('MML', inst.target) assert_equal(%| &sgr; v 10 26 |, inst.content) end def test_dtd Ox.default_options = $ox_object_options xml = Ox.dump('test', mode: :object, with_dtd: true) assert_equal("\ntest\n", xml) end def test_lone_dtd Ox.default_options = $ox_object_options xml = '' # not really a valid xml but should pass anyway doc = Ox.parse(xml) assert_equal('html', doc.nodes[0].value) end def test_big_dtd Ox.default_options = $ox_object_options xml = %{]>} doc = Ox.parse(xml) assert_equal(%{Objects []}, doc.nodes[0].value) end def test_quote_value Ox.default_options = $ox_object_options xml = %{} doc = Ox.parse(xml) assert_equal('Pete', doc.attributes[:name]) end def test_escape_value Ox.default_options = $ox_object_options xml = %{\n<not 'quoted'>\n} doc = Ox.parse(xml) assert_equal('<&test>', doc.attributes[:name]) dumped_xml = Ox.dump(doc) escaped_xml = %{\n<not 'quoted'>\n} assert_equal(escaped_xml, dumped_xml) end def test_escape_bad Ox.default_options = $ox_object_options xml = %{&example;} begin doc = Ox.parse(xml) rescue Exception => e assert_equal('Invalid format, invalid special character sequence at line 1, column 22 ', e.message.split('[')[0]) return end assert(false) end def test_escape_ignore Ox.default_options = $ox_generic_options xml = %{&example;} doc = Ox.load(xml, convert_special: false) assert_equal('&example;', doc.attributes[:name]) assert_equal('&example;', doc.nodes[0]) end def test_escape_hex_value Ox.default_options = $ox_object_options xml = %{\n\n} doc = Ox.parse(xml) assert_equal('<@test>', doc.attributes[:name]) end def test_escape_special Ox.default_options = $ox_object_options xml = %{\nπ\n} doc = Ox.parse(xml) assert_equal('π', doc.attributes[:name].force_encoding('UTF-8')) end def test_escape_dump_tolerant Ox.default_options = $ox_object_options dumped_xml = Ox.dump("tab\tamp&backspace\b.", effort: :tolerant) assert_equal("tab\tamp&backspace.\n", dumped_xml) end def test_escape_dump_strict Ox.default_options = $ox_object_options begin Ox.dump("tab\tamp&backspace\b.", effort: :strict) rescue Exception => e assert_equal("'\\#x08' is not a valid XML character.", e.message) return end assert(false) end def test_escape_dump_replace Ox.default_options = $ox_object_options dumped_xml = Ox.dump("tab\tamp&backspace\b.", effort: :tolerant, invalid_replace: '#') assert_equal("tab\tamp&backspace#.\n", dumped_xml) end def test_escape_dump_no_replace Ox.default_options = $ox_object_options dumped_xml = Ox.dump("tab\tamp&backspace\b.", effort: :tolerant, invalid_replace: nil) assert_equal("tab\tamp&backspace.\n", dumped_xml) end def test_escape_load_tolerant Ox.default_options = $ox_object_options obj = Ox.load("tab\tamp&backspace\b.", effort: :tolerant, skip: :skip_none) assert_equal("tab\tamp&backspace\b.", obj) end def test_escape_load_strict Ox.default_options = $ox_object_options begin Ox.load("tab\tamp&backspace\b.", effort: :strict) rescue Exception => e assert_equal('invalid character at line 1, column 26 ', e.message.split('[')[0]) return end assert(false) end def test_escape_utf8_value Ox.default_options = $ox_object_options xml = %{\n� test @\n} doc = Ox.parse(xml).root assert_equal('ピ test @', doc.nodes[0]) assert_equal('ピーター', doc.attributes[:name]) end def test_escape_utf8_nil_encoding Ox.default_options = $ox_object_options xml = %{\nピ test @\n} doc = Ox.parse(xml).root assert_equal('ピ test @', doc.nodes[0]) assert_equal('ピーター', doc.attributes[:name]) end def test_escape_bom_utf8_encoding Ox.default_options = $ox_object_options xml = %{\xEF\xBB\xBF\n\n} doc = Ox.parse(xml).root assert_equal('bom', doc.attributes[:name]) return if RUBY_VERSION.start_with?('1.8') # || 'rubinius' == $ruby assert_equal('UTF-8', doc.attributes[:name].encoding.to_s) end def test_escape_bom_bad_encoding Ox.default_options = $ox_object_options xml = %{\xEF\xBB\n\n} assert_raise(Ox::ParseError) do Ox.parse(xml).root end end def test_escape_open_close_tag_names Ox.default_options = $ox_object_options b = Ox::Builder.new b.element(%(/>)) { b.text('xss') } s = b.to_s assert_equal(%(xss\n), s) end def test_attr_as_string Ox.default_options = $ox_object_options xml = %{} doc = Ox.load(xml, mode: :generic, symbolize_keys: false) assert_equal(['name'], doc.attributes.keys) # Verify :name and 'name' are the same as far as attribute keys go. assert_equal('Pete', doc[:name]) assert_equal('Pete', doc['name']) doc[:name] = 'Peter' assert_equal('Peter', doc[:name]) assert_equal('Peter', doc['name']) doc['name'] = 'Pete' assert_equal('Pete', doc[:name]) assert_equal('Pete', doc['name']) assert_equal(['name'], doc.attributes.keys) end def test_single_quote Ox.default_options = $ox_generic_options xml = %{} doc = Ox.load(xml, effort: :tolerant) assert_equal('Pete', doc.attributes[:name]) end def test_no_quote Ox.default_options = $ox_generic_options xml = %{} doc = Ox.load(xml, effort: :tolerant) assert_equal('Pete', doc.attributes[:name]) end def test_skip_none Ox.default_options = $ox_object_options xml = %{ Pete\r Ohler P O} doc = Ox.load(xml, mode: :generic, symbolize_keys: false, skip: :skip_none) x2 = Ox.dump(doc, indent: -1) assert_equal(%{ Pete\n Ohler PO}, x2) end def test_skip_off Ox.default_options = $ox_object_options xml = %{ Pete\r\n Ohler P O} doc = Ox.load(xml, mode: :generic, symbolize_keys: false, skip: :skip_off) x2 = Ox.dump(doc, indent: -1) assert_equal(%{ Pete\n Ohler P O}, x2) end def test_skip_return Ox.default_options = $ox_object_options xml = %{ Pete\r\n Ohler} doc = Ox.load(xml, mode: :generic, symbolize_keys: false, skip: :skip_return) x2 = Ox.dump(doc) assert_equal(%{\n Pete\n Ohler\n}, x2) end def test_skip_return2 Ox.default_options = $ox_object_options xml = %{ Pete\rOhler} doc = Ox.load(xml, mode: :generic, symbolize_keys: false, skip: :skip_return) x2 = Ox.dump(doc) assert_equal(%{\n Pete\nOhler\n}, x2) end def test_skip_space Ox.default_options = $ox_object_options xml = %{ Pete\r\n Ohler} doc = Ox.load(xml, mode: :generic, symbolize_keys: false, skip: :skip_white) x2 = Ox.dump(doc) assert_equal(%{\n Pete Ohler\n}, x2) end def test_tolerant Ox.default_options = $ox_generic_options Ox.default_options = { skip: :skip_return } xml = %{ This is a test of the &tolerant&#x effort option. after thought } expected = %{ This is a test of the &tolerant&#x effort option. after thought } doc = Ox.load(xml, effort: :tolerant) # puts Ox.dump(doc) assert_equal(expected, Ox.dump(doc, with_xml: false)) end def test_tolerant_case Ox.default_options = $ox_generic_options xml = %{ Some text. } expected = %{ Some text. } doc = Ox.load(xml, effort: :tolerant) # puts Ox.dump(doc) assert_equal(expected, Ox.dump(doc, with_xml: false)) end def test_class Ox.default_options = $ox_object_options dump_and_load(Bag, false) end def test_exception Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby assert(true) else e = StandardError.new('Some Error') e.set_backtrace(['./func.rb:119: in test_exception', './fake.rb:57: in fake_func']) dump_and_load(e, false) end end def test_exception_bag Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') || 'rubinius' == $ruby assert(true) else xml = %{ Some Error ./func.rb:119: in test_exception ./fake.rb:57: in fake_func } x = Ox.load(xml, mode: :object, effort: :auto_define) assert_equal('Some Error', x.message) assert(x.is_a?(Exception)) end end def test_struct Ox.default_options = $ox_object_options if 'ruby' == $ruby || 'ree' == $ruby s = Struct.new('Box', :x, :y, :w, :h) dump_and_load(s.new(2, 4, 10, 20), false) else assert(true) end end def test_bad_format Ox.default_options = $ox_object_options xml = "\ntest\n" assert_raise(Ox::ParseError) do Ox.load(xml, mode: :generic, trace: 0) end end def test_array_multi Ox.default_options = $ox_object_options t = Time.local(2012, 1, 5, 23, 58, 7) dump_and_load([nil, true, false, 3, 'z', 7.9, 'a&b', :xyz, t, (-1..7)], false) end def test_hash_multi Ox.default_options = $ox_object_options t = Time.local(2012, 1, 5, 23, 58, 7) dump_and_load({ nil => nil, true => true, false => false, 3 => 3, 'z' => 'z', 7.9 => 7.9, 'a&b' => 'a&b', :xyz => :xyz, t => t, (-1..7) => (-1..7) }, false) end def test_object_multi Ox.default_options = $ox_object_options t = Time.local(2012, 1, 5, 23, 58, 7) dump_and_load(Bag.new(:@a => nil, :@b => true, :@c => false, :@d => 3, :@e => 'z', :@f => 7.9, :@g => 'a&b', :@h => :xyz, :@i => t, :@j => (-1..7)), false) end def test_complex Ox.default_options = $ox_object_options dump_and_load(Bag.new(:@o => Bag.new(:@a => [2]), :@a => [1, { b: 3, a: [5], c: Bag.new(:@x => 7) }]), false) end def test_dump_margin Ox.default_options = $ox_object_options x = Ox.dump(Bag.new(:@o => Bag.new(:@a => [2]), :@a => [1, { b: 3, a: [5], c: Bag.new(:@x => 7) }]), indent: 1, margin: '##') assert(x.include?('## ## ## 2 ## ## ')) assert(x.include?('## ## 1 ## ## b ## 3 ## a ## ## 5 ## ## c ## ## 7 ## ## ## ')) end # Create an Object and an Array with the same Objects in them. Dump and load # and then change the ones in the loaded Object to verify that the ones in # the array change in the same way. They are the same objects so they should # change. Perform the operation on both the object before and the loaded so # the equal() method can be used. def test_circular Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') # In 1.8.7 the eql? method behaves differently but the results are # correct when viewed by eye. assert(true) else a = [1] s = 'a,b,c' h = { 1 => 2 } e = Ox::Element.new('Zoo') e[:cage] = 'bear' b = Bag.new(:@a => a, :@s => s, :@h => h, :@e => e) a << s a << h a << e a << b loaded = dump_and_load(b, false, true) # modify the string loaded.instance_variable_get(:@s).gsub!(',', '_') b.instance_variable_get(:@s).gsub!(',', '_') # modify hash loaded.instance_variable_get(:@h)[1] = 3 b.instance_variable_get(:@h)[1] = 3 # modify Element loaded.instance_variable_get(:@e)['pen'] = 'zebra' b.instance_variable_get(:@e)['pen'] = 'zebra' # pp loaded assert_equal(b, loaded) end end # verify that an exception is raised if a circular ref object is created. def test_circular_limit Ox.default_options = $ox_object_options h = {} h[:h] = h begin Ox.dump(h) rescue Exception assert(true) return end assert(false) end def test_raw Ox.default_options = $ox_object_options raw = Ox::Element.new('raw') su = Ox::Element.new('sushi') su[:kind] = 'fish' raw << su ba = Ox::Element.new('basashi') ba[:kind] = 'animal' raw << ba dump_and_load(Bag.new(:@raw => raw), false) end def test_nameerror Ox.default_options = $ox_object_options begin raise StandardError.new('An error message,') rescue Exception => e xml = Ox.dump(e, effort: :tolerant) o = Ox.load(xml, mode: :object) xml2 = Ox.dump(o, effort: :tolerant) assert_equal(xml, xml2) return end assert(false) end def test_no_empty Ox.default_options = $ox_generic_options h = {} x = Ox.dump(h, no_empty: true) assert_equal(x, "\n") x = Ox.dump(Ox::Element.new('empty'), no_empty: true) assert_equal(x, "\n\n") end def test_mutex Ox.default_options = $ox_object_options if defined?(Mutex) && 'rubinius' != $ruby # Mutex can not be serialize but it should not raise an exception. xml = Ox.dump(Mutex.new, indent: 2, effort: :tolerant) assert_equal(%{ }, xml) xml = Ox.dump(Bag.new(:@x => Mutex.new), indent: 2, effort: :tolerant) assert_equal(%{ }, xml) else assert(true) end end def test_encoding Ox.default_options = $ox_object_options s = 'ピーター' xml = Ox.dump(s, with_xml: true, encoding: 'UTF-8') # puts xml # puts xml.encoding.to_s assert_equal('UTF-8', xml.encoding.to_s) obj = Ox.load(xml, mode: :object) assert_equal(s, obj) end def test_full_encoding Ox.default_options = $ox_generic_options xml = %{ <いち name="ピーター" つま="まきえ">ピーター } obj = Ox.load(xml) dumped = Ox.dump(obj, with_xml: true) assert_equal('UTF-8', dumped.encoding.to_s) assert_equal(xml, dumped) end def test_obj_encoding Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') # jruby supports in a non standard way and does not allow utf-8 encoded object attribute names assert(true) else orig = Ox.default_options opts = orig.clone opts[:encoding] = 'UTF-8' opts[:with_xml] = true Ox.default_options = opts begin # only 1.9.x rubies know how to parse a UTF-8 symbol dump_and_load(Bag.new(:@tsuma => :まきえ), false) dump_and_load(Bag.new(:@つま => :まきえ), false) ensure Ox.default_options = orig end end end def test_instructions Ox.default_options = $ox_object_options xml = Ox.dump('test', with_instructions: true) # puts xml obj = Ox.load(xml) # should convert it to an object assert_equal('test', obj) end def test_generic_string Ox.default_options = $ox_object_options xml = %{ A <boo> } doc = Ox.load(xml, mode: :generic) xml2 = Ox.dump(doc, with_xml: true) assert_equal(xml, xml2) end def test_generic_white_string Ox.default_options = $ox_generic_options xml = %{ } doc = Ox.load(xml, skip: :skip_none) assert_equal(' ', doc.root.nodes[0]) end def test_generic_encoding Ox.default_options = $ox_object_options if RUBY_VERSION.start_with?('1.8') assert(true) else xml = %{ <まきえ> } doc = Ox.load(xml, mode: :generic) xml2 = Ox.dump(doc, with_xml: true) assert_equal(xml, xml2) end end def test_IO Ox.default_options = $ox_object_options f = File.open(__FILE__, 'r') assert_raise(NotImplementedError) do Ox.dump(f, effort: :strict) end xml = Ox.dump(f, effort: :tolerant) obj = Ox.load(xml, mode: :object) # should convert it to an object assert_nil(obj) end def each_xml %{ Some text } end def test_each Ox.default_options = $ox_object_options doc = Ox.parse(each_xml) nodes = [] doc.Family.Pete.each { |n| n.is_a?(Ox::Element) && (nodes << n.id) } assert_equal(['Nicole', 'Pamela', 'Fictional'], nodes) end def test_each_name Ox.default_options = $ox_object_options doc = Ox.parse(each_xml) nodes = [] doc.Family.Pete.each('Kid') { |n| nodes << n.id } assert_equal(['Nicole', 'Pamela'], nodes) end def test_each_name_sym Ox.default_options = $ox_object_options doc = Ox.parse(each_xml) nodes = [] doc.Family.Pete.each(:Kid) { |n| nodes << n.id } assert_equal(['Nicole', 'Pamela'], nodes) end def test_each_attr Ox.default_options = $ox_object_options doc = Ox.parse(each_xml) nodes = [] doc.Family.Pete.each(gender: 'female') { |n| nodes << n.id } assert_equal(['Nicole', 'Pamela'], nodes) end def test_each_attr_multi Ox.default_options = $ox_object_options doc = Ox.parse(each_xml) nodes = [] doc.Family.Pete.each(gender: 'female', age: '31') { |n| nodes << n.id } assert_equal(['Pamela'], nodes) end def locate_xml %{ } end def test_locate_self Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate(nil) assert_equal(doc, nodes[0]) end def test_locate_top Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family') assert_equal([doc.nodes[0]], nodes) end def test_locate_top_wild Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('?') assert_equal(doc.nodes[0], nodes[0]) end def test_locate_child Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/?') assert_equal(['Pete'], nodes.map { |n| n.value }) nodes = doc.locate('Family/?/^Element') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.value }) nodes = doc.locate('Family/Pete/^Element') assert_equal(['Kid1', 'Kid2'], nodes.map { |n| n.value }) nodes = doc.locate('Family/Makie/?') assert_equal([], nodes.map { |n| n.name }) end def test_locate_comment Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('^Comment') assert_equal(['One Only'], nodes.map { |n| n.value }) end def test_locate_child_wild_wild Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/?/?') assert_equal(['Kid1', 'Nicole', 'Kid2', 'Pamela'], nodes.map { |n| n.value }) end def test_locate_child_wild Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?') assert_equal(['Kid1', 'Nicole', 'Kid2', 'Pamela'], nodes.map { |n| n.value }) end def test_locate_child_wild_missing Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Makie/?') assert_equal([], nodes.map { |n| n.name }) end def test_locate_child_comments Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/?/^Comment') assert_equal(['Nicole', 'Pamela'], nodes.map { |n| n.value }) end def test_locate_attribute Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/@?') assert_equal(['false'], nodes) nodes = doc.locate('Family/@real') assert_equal(['false'], nodes) nodes = doc.locate('Family/Pete/@?') assert_equal(['57', 'male'], nodes.sort) nodes = doc.locate('Family/Pete/@age') assert_equal(['57'], nodes) nodes = doc.locate('Family/Makie/@?') assert_equal([], nodes) nodes = doc.locate('Family/Pete/?/@age') assert_equal(['31', '32'], nodes.sort) nodes = doc.locate('Family/*/@age') assert_equal(['31', '32', '57'], nodes.sort) nodes = doc.locate('*/@?') assert_equal(['31', '32', '57', 'false', 'male'], nodes.sort) pete = doc.locate('Family/Pete')[0] nodes = pete.locate('*/@age') assert_equal(['31', '32', '57'], nodes.sort) assert_raise(::Ox::InvalidPath) do nodes = doc.locate('Family/@age/?') end assert_raise(::Ox::InvalidPath) do nodes = doc.locate('Family/?[/?') end end def test_locate_qual_index Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[0]') assert_equal(['Kid1'], nodes.map { |e| e.value } ) nodes = doc.locate('Family/Pete/?[1]') assert_equal(['Nicole'], nodes.map { |e| e.value } ) nodes = doc.locate('Family/Pete/?[2]') assert_equal(['Kid2'], nodes.map { |e| e.value } ) end def test_locate_qual_less Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[<1]') assert_equal(['Kid1'], nodes.map { |e| e.value } ) end def test_locate_qual_great Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[>1]') assert_equal(['Kid2', 'Pamela'], nodes.map { |e| e.value } ) end def test_locate_qual_last Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[-1]') assert_equal(['Pamela'], nodes.map { |e| e.value } ) end def test_locate_qual_last_attr Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[-2]/@age') assert_equal(['31'], nodes ) end def test_locate_attr_match Ox.default_options = $ox_object_options doc = Ox.parse(locate_xml) nodes = doc.locate('Family/Pete/?[@age=32]') assert_equal(['Kid1'], nodes.map { |e| e.value } ) nodes = doc.locate('Family/Pete/Kid1[@age=32]') assert_equal(['Kid1'], nodes.map { |e| e.value } ) nodes = doc.locate('Family/Pete/Kid1[@age=31]') assert_equal([], nodes.map { |e| e.value } ) end def test_locate_attr_presence parent = Ox::Element.new('Parent') son_with_job = Ox::Element.new('Son').tap do |n| n['job'] = 'a job' parent << n end son_without_job = Ox::Element.new('Son').tap { |n| parent << n } daughter_with_job = Ox::Element.new('Daughter').tap do |n| n['job'] = 'another job' parent << n end assert_equal([son_with_job, son_without_job, daughter_with_job], parent.nodes) assert_equal([son_with_job, daughter_with_job], parent.locate('?[@job]')) assert_equal([son_with_job], parent.locate('Son[@job]')) assert_equal([daughter_with_job], parent.locate('Daughter[@job]')) end def easy_xml %{ Nicole Pamela } end def test_remove_children_empty doc = Ox.parse(easy_xml) doc.remove_children assert_equal(doc, Ox.parse(easy_xml)) end def test_remove_children_single_match root = Ox.parse(easy_xml) kid = root.locate('*/Kid[@age=31]').first root.remove_children(kid) expected_doc = %{Nicole} assert_equal(root, Ox.parse(expected_doc)) end def test_remove_children_all root = Ox.parse(easy_xml) kids = root.locate('*/Kid') root.remove_children(*kids) kids_doc = %{} assert_equal(root, Ox.parse(kids_doc)) end def test_remove_children_by_path_unmatching_path doc = Ox.parse(easy_xml) doc.remove_children_by_path('unmatching_path') assert_equal(doc, Ox.parse(easy_xml)) end def test_remove_children_by_path_single_match doc = Ox.parse(easy_xml) doc.remove_children_by_path('*/Kid[@age=31]') expected_doc = %{Nicole} assert_equal(doc, Ox.parse(expected_doc)) end def test_remove_children_by_path_all doc = Ox.parse(easy_xml) doc.remove_children_by_path('*/Kid') kid_doc = %{} assert_equal(doc, Ox.parse(kid_doc)) end def test_easy_attribute Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_equal('false', doc.Family.real) assert_equal('58', doc.Family.Pete.age) end def test_easy_namespace Ox.default_options = $ox_object_options doc = Ox.parse(%{ Nicole Pamela }) assert_equal('false', doc.Ox_Test_Family.real) assert_equal('58', doc.Ox_Test_Family.Ox_Test_Pete.age) end def test_easy_attribute_missing Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_raise(NoMethodError) do doc.Family.fake end end def test_easy_element Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_equal(::Ox::Element, doc.Family.Pete.class) assert_equal('Pete', doc.Family.Pete.name) assert_equal('Nicole', doc.Family.Pete.Kid.text) assert_nil(doc.Family.Pete.text) end def test_easy_respond_to Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_equal(true, doc.respond_to?(:Family)) assert_equal(true, doc.Family.respond_to?('Pete')) assert_equal(false, doc.Family.respond_to?('Fred')) assert_equal(true, doc.Family.Pete.respond_to?('age')) assert_equal(false, doc.Family.Pete.respond_to?('email')) end def test_easy_replace_text Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) k1 = doc.Family.Pete.Kid(1) k1.replace_text('Spam') assert_equal('Spam', doc.Family.Pete.Kid(1).text) end def test_easy_element_index Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_equal('Pamela', doc.Family.Pete.Kid(1).text) end def test_easy_element_missing Ox.default_options = $ox_object_options doc = Ox.parse(easy_xml) assert_raise(NoMethodError) do doc.Family.Bob end end def test_arbitrary_raw_xml Ox.default_options = $ox_object_options root = Ox::Element.new('root') root << Ox::Raw.new('bar') assert_equal("\n\n bar\n\n", Ox.dump(root)) end def test_block Ox.default_options = $ox_generic_options results = [] Ox.load('firstsecond') do |x| results << Ox.dump(x) end assert_equal("\nfirst\n\nsecond\n\n\n", results.join) end def test_namespace_no_strip Ox.default_options = $ox_generic_options results = [] doc = Ox.load('inside') assert_equal(%| inside |, Ox.dump(doc)) end def test_namespace_strip_wild Ox.default_options = $ox_generic_options results = [] doc = Ox.load('inside', strip_namespace: true ) assert_equal(%| inside |, Ox.dump(doc)) end def test_namespace_strip Ox.default_options = $ox_generic_options Ox.default_options = { strip_namespace: 'spaced' } results = [] doc = Ox.load('inside') assert_equal(%| inside |, Ox.dump(doc)) end def test_prepend_child_invalid_node parent = Ox::Element.new('Parent') invalid_node = 12_345 assert_raise { parent.prepend_child(invalid_node) } end def test_prepend_child_when_nodes_are_empty parent = Ox::Element.new('Parent') assert_equal(parent.nodes, []) child = Ox::Element.new('Child') parent.prepend_child(child) assert_equal([child], parent.nodes) end def test_prepend_child_when_nodes_not_empty parent = Ox::Element.new('Parent') child0 = Ox::Element.new('Child0').tap { |n| parent << n } child1 = Ox::Element.new('Child1').tap { |n| parent << n } assert_equal(parent.nodes, [child0, child1]) child2 = Ox::Element.new('Child2') parent.prepend_child(child2) assert_equal([child2, child0, child1], parent.nodes) end def test_builder b = Ox::Builder.new(indent: 2) assert_equal(2, b.indent) assert_equal(1, b.line) assert_equal(1, b.column) assert_equal(0, b.pos) b.instruct(:xml, version: '1.0', encoding: 'UTF-8') assert_equal(1, b.line) assert_equal(39, b.column) assert_equal(38, b.pos) b.element('one', :a => 'ack', 'b' => "") b.element('two') assert_equal(3, b.line) assert_equal(6, b.column) assert_equal(88, b.pos) b.pop b.comment(' just a comment ') b.element('three') b.text(%|my name is Peter & <"ピーター">|) b.pop b.cdata("multi\nline\ncdata") b.raw("\n\n") b.comment(" Multi\nline\ncomment ") b.close xml = b.to_s assert_equal(%| my name is Peter & <"ピーター"> |, xml) end def test_builder_set_indent b = Ox::Builder.new(indent: 2) assert_equal(2, b.indent) b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one') b.element('two') b.indent = 0 b.text('Sample ') b.element('three', a: 'ack') b.text('sample') b.pop # b.pop # b.indent = 2 b.element('four') b.pop b.close xml = b.to_s assert_equal(%| Sample sample |, xml) end def test_builder_file filename = File.join(File.dirname(__FILE__), 'create_file_test.xml') b = Ox::Builder.file(filename, indent: 2) b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') b.element('two') b.pop b.comment(' just a comment ') b.element('three') b.text('my name is "ピーター"') b.pop b.pop b.close xml = File.read(filename) xml.force_encoding('UTF-8') assert_equal(%| my name is "ピーター" |, xml) end def test_builder_io omit 'needs fork' unless Process.respond_to?(:fork) IO.pipe do |r, w| if fork w.close xml = r.read(1000) xml.force_encoding('UTF-8') r.close assert_equal(%| my name is "ピーター" |, xml) else r.close b = Ox::Builder.io(w, indent: 2) b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') b.element('two') b.pop b.comment(' just a comment ') b.element('three') b.text('my name is "ピーター"') b.pop b.pop b.close w.close Process.exit(0) end end end def test_builder_block xml = Ox::Builder.new(indent: 2) do |b| b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') do b.element('two') {} b.comment(' just a comment ') b.element('three') do b.text('my name is "ピーター"') end end end assert_equal(%| my name is "ピーター" |, xml) end def test_builder_block_file filename = File.join(File.dirname(__FILE__), 'create_file_test.xml') Ox::Builder.file(filename, indent: 2) do |b| b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') do b.element('two') {} b.comment(' just a comment ') b.element('three') do b.text('my name is "ピーター"') end end end xml = File.read(filename) xml.force_encoding('UTF-8') assert_equal(%| my name is "ピーター" |, xml) end def test_builder_block_io omit 'needs fork' unless Process.respond_to?(:fork) IO.pipe do |r, w| if fork w.close xml = r.read(1000) xml.force_encoding('UTF-8') r.close assert_equal(%| my name is "ピーター" |, xml) else r.close Ox::Builder.io(w, indent: 2) do |b| b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') do b.element('two') {} b.comment(' just a comment ') b.element('three') do b.text('my name is "ピーター"') end end end w.close Process.exit(0) end end end def test_builder_no_newline b = Ox::Builder.new(indent: -1) b.instruct(:xml, version: '1.0', encoding: 'UTF-8') b.element('one', :a => 'ack', 'b' => 'back') b.text('hello') b.close xml = b.to_s assert_equal(%|hello|, xml) end def test_builder_text_with_invalid_characters_stripping b = Ox::Builder.new b.element('one') b.text("tab\tamp&backspace\b.", true) b.close xml = b.to_s assert_equal(%|tab\tamp&backspace. |, xml) end def test_builder_text_without_invalid_characters_stripping begin b = Ox::Builder.new b.element('one') b.text("tab\tamp&backspace\b.") rescue Exception => e assert_equal("'\\#x08' is not a valid XML character.", e.message) return end assert(false) end def test_builder_text_with_too_few_args begin b = Ox::Builder.new b.text rescue ArgumentError => e assert_equal('wrong number of arguments (given 0, expected 1..2)', e.message) return end assert(false) end def test_builder_text_with_too_many_args begin b = Ox::Builder.new b.text('Hello', false, 'world') rescue ArgumentError => e assert_equal('wrong number of arguments (given 3, expected 1..2)', e.message) return end assert(false) end def test_hash_no_attrs_mode_simple Ox.default_options = $ox_generic_options xml = %{This is the top. } doc = Ox.load(xml, mode: :hash) assert_equal({ top: 'This is the top.' }, doc) end def test_hash_no_attrs_mode_simple_nested Ox.default_options = $ox_generic_options xml = %{ This is a one. alpha bravo } doc = Ox.load(xml, mode: :hash) assert_equal({ top: { one: 'This is a one.', mid: { a: 'alpha', b: 'bravo' } } }, doc) end def test_hash_no_attrs_mode_multi_text Ox.default_options = $ox_generic_options xml = %{FirstSecondThird } doc = Ox.load(xml, mode: :hash) assert_equal({ top: ['First', { empty: nil }, 'Second', { empty: nil }, 'Third'] }, doc) end def test_hash_mode_simple Ox.default_options = $ox_generic_options xml = %{This is the top. } doc = Ox.load(xml, mode: :hash) assert_equal({ top: 'This is the top.' }, doc) end def test_hash_mode_simple_nested Ox.default_options = $ox_generic_options xml = %{ This is a one. alpha bravo } doc = Ox.load(xml, mode: :hash) assert_equal({ top: { one: 'This is a one.', mid: { a: 'alpha', b: 'bravo' } } }, doc) end def test_hash_mode_simple_cdata Ox.default_options = $ox_generic_options xml = %{ This is a one. } doc = Ox.load(xml, mode: :hash, with_cdata: true) assert_equal({ top: { one: 'This is a one.', mid: { a: 'alpha', b: 'bravo' } } }, doc) doc = Ox.load(xml, mode: :hash, with_cdata: false) assert_equal({ top: { one: 'This is a one.', mid: { a: nil, b: nil } } }, doc) end def test_hash_mode_multi_text Ox.default_options = $ox_generic_options xml = %{FirstSecondThird } doc = Ox.load(xml, mode: :hash) assert_equal({ top: ['First', { empty: nil }, 'Second', { empty: nil }, 'Third'] }, doc) end def test_hash_mode_simple_attrs Ox.default_options = $ox_generic_options xml = %{This is the top. } doc = Ox.load(xml, mode: :hash) assert_equal({ top: [{ type: 'string' }, 'This is the top.'] }, doc) end def test_hash_mode_attrs Ox.default_options = $ox_generic_options xml = %{ 14 14 12 14 } doc = Ox.load(xml, mode: :hash) assert_equal({ result: { variables: { var: [ [{ name: 'Blue' }, '14'], [{ name: 'Jack' }, '14'], [{ name: 'Magenta' }, '12'], [{ name: 'Yellow' }, '14'] ] } } }, doc) end def test_hash_mode_attrs2 Ox.default_options = $ox_generic_options xml = %{ 14 14 12 14 } doc = Ox.load(xml, mode: :hash) assert_equal({ result: { variables: { var: [ '14', [{ name: 'Jack' }, '14'], [{ name: 'Magenta' }, '12'], [{ name: 'Yellow' }, '14'] ] } } }, doc) end def test_hash_mode_attrs3 Ox.default_options = $ox_generic_options xml = %{ 14 14 12 14 } doc = Ox.load(xml, mode: :hash) assert_equal({ result: { variables: { var: [ [{ name: 'Blue' }, '14'], '14', [{ name: 'Magenta' }, '12'], [{ name: 'Yellow' }, '14'] ] } } }, doc) end def test_key_mod Ox.default_options = $ox_object_options xml = %{ } ep = lambda { |k| k.downcase } ap = lambda { |k| 'a' + k } doc = Ox.load(xml, mode: :generic, attr_key_mod: ap, element_key_mod: ep ) xml2 = Ox.dump(doc) assert_equal(%{ }, xml2) end def test_encoding_ascii Ox.default_options = $ox_generic_options xml = 'Héraïdios'.force_encoding(Encoding::ASCII_8BIT) text = Ox.load(xml).root.text assert_equal('Héraïdios', text) assert_equal(Encoding::UTF_8, text.encoding) end def dump_and_load(obj, trace=false, circular=false) xml = Ox.dump(obj, indent: $indent, circular: circular) puts xml if trace loaded = Ox.load(xml, trace: (trace ? 2 : 0)) if obj.nil? assert_nil(loaded) else assert_equal(obj, loaded) end loaded end end class Bag def initialize(args) args.each do |k, v| instance_variable_set(k, v) end end def eql?(other) return false if (other.nil? or self.class != other.class) ova = other.instance_variables return false if ova.size != instance_variables.size instance_variables.each do |vid| return false if instance_variable_get(vid) != other.instance_variable_get(vid) end true end alias == eql? end ox-2.14.17/test/weather/000077500000000000000000000000001445411231300147305ustar00rootroot00000000000000ox-2.14.17/test/weather/HellsGate_2012_weather.xml000066400000000000000000101522751445411231300215220ustar00rootroot00000000000000 Ohler Peter Ohler Peter 2012-04-03T03:05:35Z Home 14.0 17740 26080 0 0 False False CODE DATETIME OBS TYPE MAX TEMP PRES TEMP MIN TEMP RH DEW_POINT HRLY_PRCP NEW PRCP PRCP GAUGE NEW SNOW SNOW PACK PRECIP_DET_RATIO WND SPD MEAS MAX_GUST_1 WND_DIR_1 STD_DEV_1 ATM PRESSURE 15123 2012-01-01T00:00:00.000 RAW -5.1790000000000003 -6.3319999999999999 -6.4690000000000003 0 0 0 81.3 0.05 2.0779999999999998 2.5059999999999998 12.61 15123 2012-01-01T01:00:00.000 RAW -5.1790000000000003 -6.4489999999999998 -6.4790000000000001 0 0 0 81.099999999999994 8.9999999999999993E-3 1.071 8.68 7.13 15123 2012-01-01T02:00:00.000 RAW -5.1790000000000003 -6.43 -6.4790000000000001 0 0 0 81 1E-3 0.189 345.8 2.7530000000000001 15123 2012-01-01T03:00:00.000 RAW -5.1790000000000003 -6.1959999999999997 -6.4790000000000001 0 0 0 80.8 2E-3 0.315 348.1 4.6399999999999997 15123 2012-01-01T04:00:00.000 RAW -5.1790000000000003 -6.1959999999999997 -6.4790000000000001 0 0 0 80.599999999999994 1.0999999999999999E-2 1.1970000000000001 332.7 4.2770000000000001 15123 2012-01-01T05:00:00.000 RAW -5.1790000000000003 -6.06 -6.4790000000000001 0 0 0 80.400000000000006 0 6.3E-2 245.8 5.6120000000000001 15123 2012-01-01T06:00:00.000 ST -5.1790000000000003 -6.1470000000000002 -6.4790000000000001 0 0 0 80.5 1.2999999999999999E-2 1.008 9.27 7.01 15123 2012-01-01T07:00:00.000 RAW -6.0990000000000002 -6.2539999999999996 -6.2640000000000002 0 0 0 80.5 1E-3 0.252 359.9 2.89 15123 2012-01-01T08:00:00.000 RAW -5.9429999999999996 -5.9909999999999997 -6.2640000000000002 0 0 0 80.400000000000006 1E-3 0.126 34.54 4.194 15123 2012-01-01T09:00:00.000 RAW -5.4589999999999996 -5.4589999999999996 -6.2640000000000002 0 0 0 80.3 1E-3 0.189 336.8 1.9119999999999999 15123 2012-01-01T10:00:00.000 RAW -4.4000000000000004 -4.4000000000000004 -6.2640000000000002 0 0 0 80.2 2E-3 0.189 333.7 1.3620000000000001 15123 2012-01-01T11:00:00.000 RAW -3.0819999999999999 -3.0819999999999999 -6.2640000000000002 0 0 0 79.599999999999994 0 6.3E-2 341.8 0.68200000000000005 15123 2012-01-01T12:00:00.000 RAW -2.5209999999999999 -3.0169999999999999 -6.2640000000000002 0 0 0 79.7 1E-3 6.3E-2 340.5 1.2290000000000001 15123 2012-01-01T13:00:00.000 RAW -1.972 -1.972 -6.2640000000000002 0 0 0 79.5 0 0 0 0 15123 2012-01-01T14:00:00.000 RAW -1.887 -2.4089999999999998 -6.2640000000000002 0 0 0 79.599999999999994 1E-3 0.189 346.7 0.69299999999999995 15123 2012-01-01T15:00:00.000 RAW -1.887 -2.3519999999999999 -6.2640000000000002 0 0 0 79.5 1E-3 0.126 348.4 0.35099999999999998 15123 2012-01-01T16:00:00.000 RAW -1.887 -2.7229999999999999 -6.2640000000000002 0 0 0 79.8 0 6.3E-2 12.46 3.9969999999999999 15123 2012-01-01T17:00:00.000 RAW -1.887 -2.7309999999999999 -6.2640000000000002 0 0 0 79.5 4.0000000000000001E-3 0.56699999999999995 359.4 2.7629999999999999 15123 2012-01-01T18:00:00.000 ST -1.887 -2.4359999999999999 -6.2640000000000002 0 0 0 79.599999999999994 3.0000000000000001E-3 0.441 20.29 5.6609999999999996 15123 2012-01-01T19:00:00.000 RAW -2.2930000000000001 -2.806 -2.835 0 0 0 78.8 0 0 0 0 15123 2012-01-01T20:00:00.000 RAW -2.2930000000000001 -2.7210000000000001 -2.8540000000000001 0 0 0 78.7 1E-3 0.126 331.8 1.5229999999999999 15123 2012-01-01T21:00:00.000 RAW -2.2930000000000001 -2.835 -2.8919999999999999 0 0 0 79 0 0 0 0 15123 2012-01-01T22:00:00.000 RAW -2.2930000000000001 -3.2250000000000001 -3.2440000000000002 0 0 0 78.900000000000006 0 0 0 0 15123 2012-01-01T23:00:00.000 RAW -2.2930000000000001 -3.101 -3.2719999999999998 0 0 0 78.2 4.3999999999999997E-2 1.7 186.4 1.573 15123 2012-01-02T00:00:00.000 RAW -2.2930000000000001 -2.7010000000000001 -3.2719999999999998 0 0 0 78.400000000000006 0.33200000000000002 8.6300000000000008 172 3.6240000000000001 15123 2012-01-02T01:00:00.000 RAW -2.0840000000000001 -2.0840000000000001 -3.2719999999999998 0 0 0 78.3 0.01 0.81899999999999995 184.6 1.282 15123 2012-01-02T02:00:00.000 RAW -1.8280000000000001 -1.9610000000000001 -3.2719999999999998 0 0 0 78.2 8.0000000000000002E-3 0.755 182.9 0.90500000000000003 15123 2012-01-02T03:00:00.000 RAW -1.43 -1.4870000000000001 -3.2719999999999998 0 0 0 78.3 0.23499999999999999 8.3699999999999992 181.5 0.57199999999999995 15123 2012-01-02T04:00:00.000 RAW -1.383 -1.601 -3.2719999999999998 0 0 0 78.2 0.11799999999999999 5.7290000000000001 161.4 6.2050000000000001 15123 2012-01-02T05:00:00.000 RAW -1.3260000000000001 -1.3360000000000001 -3.2719999999999998 0 0 0 78.3 8.0000000000000002E-3 0.56699999999999995 171 1.9610000000000001 15123 2012-01-02T06:00:00.000 ST -0.53100000000000003 -0.53100000000000003 -3.2719999999999998 0 0 0 77.599999999999994 1.0999999999999999E-2 1.0069999999999999 173.3 1.6910000000000001 15123 2012-01-02T07:00:00.000 RAW -0.502 -0.61599999999999999 -0.71099999999999997 0 0 0 76.8 1.0549999999999999 8.25 162.9 4.4080000000000004 15123 2012-01-02T08:00:00.000 RAW -0.502 -0.80600000000000005 -0.92 0 0 0 76.8 0.54200000000000004 4.7220000000000004 173.8 4.3460000000000001 15123 2012-01-02T09:00:00.000 RAW -0.502 -0.98599999999999999 -1.0329999999999999 0 0 0 76.2 0.59299999999999997 9.6999999999999993 173.6 4.5949999999999998 15123 2012-01-02T10:00:00.000 RAW 0.26300000000000001 0.26300000000000001 -1.0329999999999999 0 0 0 75.900000000000006 0.34300000000000003 7.37 190.3 3.0139999999999998 15123 2012-01-02T11:00:00.000 RAW 0.61299999999999999 0.61299999999999999 -1.0329999999999999 0 0 0 75.8 0.81100000000000005 9.51 176.6 8.4 15123 2012-01-02T12:00:00.000 RAW 0.96199999999999997 0.95199999999999996 -1.0329999999999999 0 0 0 74.900000000000006 1.774 10.57 182.5 14.27 15123 2012-01-02T13:00:00.000 RAW 1.8320000000000001 1.8129999999999999 -1.0329999999999999 0 0 0 73.5 3.968 20.58 160.80000000000001 12.92 15123 2012-01-02T14:00:00.000 RAW 2.58 1.879 -1.0329999999999999 0 0 0 73.3 1.9750000000000001 16.86 173.1 6.8109999999999999 15123 2012-01-02T15:00:00.000 RAW 2.6459999999999999 2.6269999999999998 -1.0329999999999999 0 0 0 77.2 9.84 32.47 163.80000000000001 30.53 15123 2012-01-02T16:00:00.000 RAW 2.694 2.419 -1.0329999999999999 0 0 0 76.3 8.5299999999999994 23.09 178.9 31.74 15123 2012-01-02T17:00:00.000 RAW 2.694 2.1160000000000001 -1.0329999999999999 0 0 0 77.3 7.52 22.91 169.9 18.36 15123 2012-01-02T18:00:00.000 ST 2.694 2.1829999999999998 -1.0329999999999999 0 0 0.1 77.400000000000006 2.5249999999999999 14.54 157.80000000000001 13.85 15123 2012-01-02T19:00:00.000 RAW 2.1829999999999998 1.6240000000000001 1.387 0 0 0 77 4.7720000000000002 16.11 158.6 19.09 15123 2012-01-02T20:00:00.000 RAW 2.1829999999999998 1.5289999999999999 1.387 0 0 0 77.2 2.0609999999999999 9.94 144.9 12.22 15123 2012-01-02T21:00:00.000 RAW 2.1829999999999998 1.056 1.056 0 0 0 76.7 4.6879999999999997 16.87 141.30000000000001 13.55 15123 2012-01-02T22:00:00.000 RAW 2.1829999999999998 0.65900000000000003 0.65900000000000003 0 0 0 76.5 9.66 19.07 139.80000000000001 16.03 15123 2012-01-02T23:00:00.000 RAW 2.1829999999999998 0.28000000000000003 0.28000000000000003 0 0 0 76.2 9.3000000000000007 27.5 140.1 24.42 15123 2012-01-03T00:00:00.000 RAW 2.1829999999999998 0.66900000000000004 0.24299999999999999 0 0 0 76 12.95 31.59 140.69999999999999 26.46 15123 2012-01-03T01:00:00.000 RAW 2.1829999999999998 1.113 0.24299999999999999 0 0 0 75.7 12.19 32.03 144 29.29 15123 2012-01-03T02:00:00.000 RAW 2.1829999999999998 1.331 0.24299999999999999 0 0 0 75.400000000000006 12.95 29.96 145.9 28.44 15123 2012-01-03T03:00:00.000 RAW 2.1829999999999998 0.93300000000000005 0.24299999999999999 0 0 0 74.8 12.45 30.96 146.80000000000001 26.86 15123 2012-01-03T04:00:00.000 RAW 2.1829999999999998 0.88600000000000001 0.24299999999999999 0 0 0 74.599999999999994 12.24 28.51 136.69999999999999 22.5 15123 2012-01-03T05:00:00.000 RAW 2.1829999999999998 0.78200000000000003 0.24299999999999999 0 0 0 74.5 10.51 24.1 137.19999999999999 23.31 15123 2012-01-03T06:00:00.000 ST 2.1829999999999998 0.64 0.24299999999999999 0 0 0 74.099999999999994 8.84 26.12 133.80000000000001 23.77 15123 2012-01-03T07:00:00.000 RAW 0.67800000000000005 0.64 0.57399999999999995 0 0 0 73.7 8.35 23.1 142.4 30.91 15123 2012-01-03T08:00:00.000 RAW 0.67800000000000005 0.50800000000000001 0.50800000000000001 0 0 0 73.400000000000006 8.7799999999999994 27.44 143.69999999999999 35.130000000000003 15123 2012-01-03T09:00:00.000 RAW 0.78200000000000003 0.78200000000000003 0.47 0 0 0 73.5 7.23 23.1 141.9 29.46 15123 2012-01-03T10:00:00.000 RAW 1.1220000000000001 1.113 0.47 0 0 0 73.5 8.34 19.7 141.80000000000001 23.51 15123 2012-01-03T11:00:00.000 RAW 1.5669999999999999 1.5389999999999999 0.47 0 0 0 73.7 7.24 18.5 149.1 22.25 15123 2012-01-03T12:00:00.000 RAW 1.5860000000000001 1.415 0.47 0 0 0 73.400000000000006 8.34 23.6 141.4 24.08 15123 2012-01-03T13:00:00.000 RAW 1.5860000000000001 1.0940000000000001 0.47 0 0 0 73.3 9.09 23.98 133.4 24.6 15123 2012-01-03T14:00:00.000 RAW 1.5860000000000001 0.91400000000000003 0.47 0 0 0 73.099999999999994 10.02 27.12 138.69999999999999 23.25 15123 2012-01-03T15:00:00.000 RAW 1.5860000000000001 0.79100000000000004 0.47 0 0 0 72.900000000000006 10.220000000000001 21.77 136.9 18.87 15123 2012-01-03T16:00:00.000 RAW 1.5860000000000001 0.40300000000000002 0.38500000000000001 0 0 0 72.8 9.92 22.15 136.9 17.13 15123 2012-01-03T17:00:00.000 RAW 1.5860000000000001 0.42299999999999999 0.375 0 0 0 72.8 10.36 19.45 136.19999999999999 14.48 15123 2012-01-03T18:00:00.000 ST 1.5860000000000001 0.47 0.28100000000000003 0 0 0 72.599999999999994 11.48 23.35 138.4 15.26 15123 2012-01-03T19:00:00.000 RAW 0.59299999999999997 0.56499999999999995 0.46100000000000002 0 0 0 72.3 11.4 28.38 135.1 22.9 15123 2012-01-03T20:00:00.000 RAW 0.91500000000000004 0.84899999999999998 0.46100000000000002 0 0 0 72.2 9.9600000000000009 19.89 134.5 27.38 15123 2012-01-03T21:00:00.000 RAW 1.302 1.302 0.46100000000000002 0 0 0 71.8 10.66 21.46 137.4 26.1 15123 2012-01-03T22:00:00.000 RAW 1.738 1.738 0.46100000000000002 0 0 0 71.3 10.01 22.59 140.5 25.99 15123 2012-01-03T23:00:00.000 RAW 1.766 1.738 0.46100000000000002 0 0 0 70.3 7.73 18 139.4 24.03 15123 2012-01-04T00:00:00.000 RAW 2.1160000000000001 2.097 0.46100000000000002 0 0 0 68.680000000000007 8.0399999999999991 19.260000000000002 137.4 18.29 15123 2012-01-04T01:00:00.000 RAW 2.6280000000000001 2.6179999999999999 0.46100000000000002 0 0 0 70.7 7.22 18.690000000000001 146.80000000000001 15.69 15123 2012-01-04T02:00:00.000 RAW 3.121 3.121 0.46100000000000002 0 0 0 70.3 5.0090000000000003 16.68 147.30000000000001 15.87 15123 2012-01-04T03:00:00.000 RAW 3.254 3.13 0.46100000000000002 0 0 0 69.36 5.2919999999999998 12.4 137.80000000000001 14.79 15123 2012-01-04T04:00:00.000 RAW 3.6709999999999998 3.6429999999999998 0.46100000000000002 0 0 0 68.83 6.7450000000000001 13.84 141.6 15.62 15123 2012-01-04T05:00:00.000 RAW 3.7090000000000001 3.69 0.46100000000000002 0 0 0 69.11 7.99 14.28 145.80000000000001 11.61 15123 2012-01-04T06:00:00.000 ST 3.88 3.2530000000000001 0.46100000000000002 0 0 0 69.58 4.2889999999999997 13.4 143 10.71 15123 2012-01-04T07:00:00.000 RAW 3.681 3.51 2.7589999999999999 0 0 0 69.5 2.387 14.28 176.8 27.07 15123 2012-01-04T08:00:00.000 RAW 3.681 2.4089999999999998 2.4089999999999998 0 0 0 68.19 5.4989999999999997 20.95 178.8 21.21 15123 2012-01-04T09:00:00.000 RAW 3.681 1.841 1.831 0 0 0 67.44 5.1349999999999998 17.809999999999999 166.5 29.64 15123 2012-01-04T10:00:00.000 RAW 3.681 1.3109999999999999 1.216 0 0 0 68.36 7.33 27.75 152.69999999999999 34.020000000000003 15123 2012-01-04T11:00:00.000 RAW 3.681 0.88600000000000001 0.88600000000000001 0 0 0 68.849999999999994 8.43 33.42 155.5 33.83 15123 2012-01-04T12:00:00.000 RAW 3.681 0.57399999999999995 0.56399999999999995 0 0 0 68.97 8.26 28.57 153.5 33.090000000000003 15123 2012-01-04T13:00:00.000 RAW 3.681 0.40400000000000003 0.28100000000000003 0 0 0 68.819999999999993 6.9329999999999998 24.17 151.30000000000001 32.9 15123 2012-01-04T14:00:00.000 RAW 3.681 0.252 0.252 0 0 0 68.36 7.9 23.29 153.69999999999999 32.159999999999997 15123 2012-01-04T15:00:00.000 RAW 3.681 0.48899999999999999 0.24299999999999999 0 0 0 68.09 7.19 23.48 148 30.65 15123 2012-01-04T16:00:00.000 RAW 3.681 1.028 0.24299999999999999 0 0 0 68.38 4.8719999999999999 18.82 154.5 25.97 15123 2012-01-04T17:00:00.000 RAW 3.681 1.264 0.24299999999999999 0 0 0 68.209999999999994 4.6559999999999997 16.05 163.69999999999999 27.33 15123 2012-01-04T18:00:00.000 ST 3.681 1.482 0.24299999999999999 0 0 0 68.09 8.01 18.82 166.5 29.03 15123 2012-01-04T19:00:00.000 RAW 2.1070000000000002 2.1070000000000002 1.444 0 0 0 68.03 6.2050000000000001 20.010000000000002 157 28.77 15123 2012-01-04T20:00:00.000 RAW 2.4670000000000001 2.4289999999999998 1.444 0 0 0 67.900000000000006 8.98 32.79 136.9 30.73 15123 2012-01-04T21:00:00.000 RAW 2.76 2.2389999999999999 1.444 0 0 0 68.2 14.87 52.17 159.69999999999999 35.700000000000003 15123 2012-01-04T22:00:00.000 RAW 2.903 2.3149999999999999 1.444 0 0 0 68.06 15.27 78.5 210.1 42.43 15123 2012-01-04T23:00:00.000 RAW 2.903 2.173 1.444 0 0 0 68.05 12.44 39.96 186.2 32.380000000000003 15123 2012-01-05T00:00:00.000 RAW 2.903 1.2170000000000001 1.2170000000000001 0 0 1 68.41 11.91 29.52 181.7 27.15 15123 2012-01-05T01:00:00.000 RAW 2.903 0.71499999999999997 0.71499999999999997 0 0 1 68.39 10.64 33.29 166.1 25.47 15123 2012-01-05T02:00:00.000 RAW 2.903 0.27100000000000002 0.27100000000000002 0 0 1 68.05 10.27 31.41 158.69999999999999 24.97 15123 2012-01-05T03:00:00.000 RAW 2.903 0.215 6.3E-2 0 0 1 68.39 13 38.450000000000003 174 31.18 15123 2012-01-05T04:00:00.000 RAW 2.903 -0.04 -9.7000000000000003E-2 0 0 1 67.8 11.58 31.53 166.9 27.29 15123 2012-01-05T05:00:00.000 RAW 2.903 -0.21099999999999999 -0.25800000000000001 0 0 1 68.06 12.42 30.08 159.1 24.04 15123 2012-01-05T06:00:00.000 ST 2.903 -0.39 -0.39 0 0 1 65.7 11.8 29.89 157.5 29.77 15123 2012-01-05T07:00:00.000 RAW -0.39 -0.64600000000000002 -0.64600000000000002 0 0 3 68.45 11.45 30.9 150 28.79 15123 2012-01-05T08:00:00.000 RAW -0.39 -0.95799999999999996 -0.95799999999999996 0 0 4 69.83 14.65 37.33 162.1 29.7 15123 2012-01-05T09:00:00.000 RAW -0.39 -1.2609999999999999 -1.2609999999999999 0 0 4 68.14 14.52 37.39 164.1 29.09 15123 2012-01-05T10:00:00.000 RAW -0.39 -1.3939999999999999 -1.4119999999999999 0 0 12.23 27.76 158.30000000000001 27.45 15123 2012-01-05T11:00:00.000 RAW -0.39 -1.716 -1.744 0 0 4 69.55 14.54 38.15 155.9 30.95 15123 2012-01-05T12:00:00.000 RAW -0.39 -1.6020000000000001 -1.7729999999999999 0 0 4 65.27 11.79 30.47 147.1 27.83 15123 2012-01-05T13:00:00.000 RAW -0.39 -1.9810000000000001 -2.0379999999999998 0 0 4 69.16 16.79 40.409999999999997 160.9 26.85 15123 2012-01-05T14:00:00.000 RAW -0.39 -1.63 -2.0379999999999998 0 0 5 69.849999999999994 13.99 35.82 178.2 23.18 15123 2012-01-05T15:00:00.000 RAW -0.39 -1.887 -2.0379999999999998 0 0 7 72.2 11.64 24.55 164.7 21.57 15123 2012-01-05T16:00:00.000 RAW -0.39 -1.8109999999999999 -2.0379999999999998 0 0 7 71.8 10.48 19.89 141.9 19.3 15123 2012-01-05T17:00:00.000 RAW -0.39 -1.829 -2.0379999999999998 0 0 7 70.599999999999994 12.15 26.25 152.19999999999999 25.05 15123 2012-01-05T18:00:00.000 ST -0.39 -1.677 -2.0379999999999998 0 0 9 73.099999999999994 12.27 26.88 153.6 28.11 15123 2012-01-05T19:00:00.000 RAW -1.583 -1.5920000000000001 -1.677 0 0 0 71.099999999999994 8.08 18.95 144.69999999999999 22.67 15123 2012-01-05T20:00:00.000 RAW -1.5349999999999999 -1.583 -1.677 0 0 0.1 73.2 3.9319999999999999 15.99 140.30000000000001 15.75 15123 2012-01-05T21:00:00.000 RAW -1.5349999999999999 -1.5920000000000001 -1.677 0 0 0 72.5 4.0670000000000002 14.67 143.5 23.29 15123 2012-01-05T22:00:00.000 RAW -1.5349999999999999 -1.7629999999999999 -1.7629999999999999 0 0 0 72.099999999999994 3.875 17.059999999999999 140.30000000000001 18.77 15123 2012-01-05T23:00:00.000 RAW -1.5349999999999999 -1.839 -1.839 0 0 2 74.5 3.0369999999999999 18.260000000000002 143.80000000000001 18.64 15123 2012-01-06T00:00:00.000 RAW -1.5349999999999999 -2.4460000000000002 -2.4929999999999999 0 0 2 74.5 6.2830000000000004 17.88 147.6 17.600000000000001 15123 2012-01-06T01:00:00.000 RAW -1.5349999999999999 -1.962 -2.5310000000000001 0 0 2 74.400000000000006 4.7809999999999997 17.88 145.6 24.7 15123 2012-01-06T02:00:00.000 RAW -1.5349999999999999 -2.0089999999999999 -2.5310000000000001 0 0 4 75.400000000000006 6.524 16.309999999999999 147.1 22.3 15123 2012-01-06T03:00:00.000 RAW -1.5349999999999999 -2.1989999999999998 -2.5310000000000001 0 0 4 73.8 10.210000000000001 25.81 154.80000000000001 24.4 15123 2012-01-06T04:00:00.000 RAW -1.5349999999999999 -2.4460000000000002 -2.5310000000000001 0 0 4 71.3 10 21.09 151 26.55 15123 2012-01-06T05:00:00.000 RAW -1.5349999999999999 -2.7210000000000001 -2.7210000000000001 0 0 4 74.2 9.9700000000000006 23.55 146.19999999999999 24.34 15123 2012-01-06T06:00:00.000 ST -1.5349999999999999 -3.1120000000000001 -3.1120000000000001 0 0 4 74.900000000000006 10.09 21.41 148.5 24.98 15123 2012-01-06T07:00:00.000 RAW -3.1019999999999999 -3.5019999999999998 -3.5019999999999998 0 0 0 74.8 9.35 19.2 146.4 22.7 15123 2012-01-06T08:00:00.000 RAW -3.1019999999999999 -3.673 -3.6930000000000001 0 0 0 74.8 10.81 24.55 159 22.73 15123 2012-01-06T09:00:00.000 RAW -3.1019999999999999 -3.4830000000000001 -3.7120000000000002 0 0 0 74.7 9.9600000000000009 18.13 152.80000000000001 16.82 15123 2012-01-06T10:00:00.000 RAW -3.1019999999999999 -3.32 -3.7120000000000002 0 0 0 74.5 7.66 18.260000000000002 143.80000000000001 16.91 15123 2012-01-06T11:00:00.000 RAW -3.0920000000000001 -3.1589999999999998 -3.7120000000000002 0 0 0 71.400000000000006 7.38 17.190000000000001 142 19.46 15123 2012-01-06T12:00:00.000 RAW -3.0350000000000001 -3.0350000000000001 -3.7120000000000002 0 0 7.27 17.88 141.4 20.52 15123 2012-01-06T13:00:00.000 RAW -2.8170000000000002 -2.8260000000000001 -3.7120000000000002 0 0 0 65.459999999999994 7.12 15.42 147.30000000000001 16.260000000000002 15123 2012-01-06T14:00:00.000 RAW -2.8069999999999999 -2.8450000000000002 -3.7120000000000002 0 0 0 65.489999999999995 7.63 15.87 146.69999999999999 16.28 15123 2012-01-06T15:00:00.000 RAW -2.8069999999999999 -2.9119999999999999 -3.7120000000000002 0 0 1 74.599999999999994 6.9889999999999999 16.43 145.9 20.18 15123 2012-01-06T16:00:00.000 RAW -2.8069999999999999 -3.121 -3.7120000000000002 0 0 1 74.8 4.4089999999999998 14.8 147.80000000000001 14.52 15123 2012-01-06T17:00:00.000 RAW -2.8069999999999999 -3.2349999999999999 -3.7120000000000002 0 0 1 74.8 6.4589999999999996 15.3 145.6 14.53 15123 2012-01-06T18:00:00.000 ST -2.8069999999999999 -3.3879999999999999 -3.7120000000000002 0 0 1 74.7 5.0309999999999997 13.72 141.30000000000001 15.13 15123 2012-01-06T19:00:00.000 RAW -3.3679999999999999 -3.444 -3.4540000000000002 0 0 0 74.5 9.32 18.010000000000002 149.69999999999999 18.3 15123 2012-01-06T20:00:00.000 RAW -3.3679999999999999 -3.569 -3.569 0 0 0 74.5 7.13 16.12 149.5 15.14 15123 2012-01-06T21:00:00.000 RAW -3.3679999999999999 -3.6160000000000001 -3.6349999999999998 0 0 0 74.400000000000006 5.758 13.35 142.1 14.58 15123 2012-01-06T22:00:00.000 RAW -3.3679999999999999 -3.6349999999999998 -3.7879999999999998 0 0 0 74.2 6.6689999999999996 15.99 144.1 16.920000000000002 15123 2012-01-06T23:00:00.000 RAW -3.3679999999999999 -3.8929999999999998 -3.8929999999999998 0 0 0 74.2 4.9560000000000004 19.52 143.69999999999999 16.010000000000002 15123 2012-01-07T00:00:00.000 RAW -3.3679999999999999 -3.6829999999999998 -4.0270000000000001 0 0 0 74 2.6859999999999999 14.04 149.80000000000001 22.16 15123 2012-01-07T01:00:00.000 RAW -3.3679999999999999 -3.6539999999999999 -4.0270000000000001 0 0 0 73.900000000000006 2.8119999999999998 15.11 149.1 17.12 15123 2012-01-07T02:00:00.000 RAW -3.3679999999999999 -3.8359999999999999 -4.0270000000000001 0 0 0 73.8 3.4159999999999999 12.02 143.30000000000001 18.510000000000002 15123 2012-01-07T03:00:00.000 RAW -3.3679999999999999 -3.9119999999999999 -4.056 0 0 0 73.599999999999994 4.9269999999999996 13.54 147.80000000000001 19.23 15123 2012-01-07T04:00:00.000 RAW -3.3679999999999999 -3.673 -4.056 0 0 0 73.5 5.5110000000000001 18.010000000000002 146.4 20 15123 2012-01-07T05:00:00.000 RAW -3.3679999999999999 -3.6160000000000001 -4.056 0 0 0 73.400000000000006 8.01 17.25 150.80000000000001 18.95 15123 2012-01-07T06:00:00.000 ST -3.3679999999999999 -3.4540000000000002 -4.056 0 0 0 73.400000000000006 7.19 17.38 146.80000000000001 16.75 15123 2012-01-07T07:00:00.000 RAW -3.4249999999999998 -3.4729999999999999 -3.4729999999999999 0 0 0 73.2 5.3739999999999997 15.74 151.30000000000001 17.100000000000001 15123 2012-01-07T08:00:00.000 RAW -3.4249999999999998 -3.4729999999999999 -3.492 0 0 0 73.2 4.726 13.03 155.19999999999999 17.48 15123 2012-01-07T09:00:00.000 RAW -3.2440000000000002 -3.2440000000000002 -3.492 0 0 0 73.099999999999994 5.056 17.88 150.19999999999999 17.72 15123 2012-01-07T10:00:00.000 RAW -2.9969999999999999 -2.9969999999999999 -3.492 0 0 0.1 73.5 6.569 15.61 143.19999999999999 19.309999999999999 15123 2012-01-07T11:00:00.000 RAW -2.883 -2.8919999999999999 -3.492 0 0 1 74.3 6.9829999999999997 19.71 145.9 23.13 15123 2012-01-07T12:00:00.000 RAW -2.7210000000000001 -2.7879999999999998 -3.492 0 0 2 75 7.27 22.16 146.5 23.98 15123 2012-01-07T13:00:00.000 RAW -2.569 -2.6640000000000001 -3.492 0 0 2 75 9.2899999999999991 20.079999999999998 143 20.85 15123 2012-01-07T14:00:00.000 RAW -2.569 -2.617 -3.492 0 0 2 74.900000000000006 8.92 22.79 142.80000000000001 15.49 15123 2012-01-07T15:00:00.000 RAW -2.4929999999999999 -2.5409999999999999 -3.492 0 0 2 75.099999999999994 8.11 16.37 141.69999999999999 14.15 15123 2012-01-07T16:00:00.000 RAW -2.3029999999999999 -2.4929999999999999 -3.492 0 0 3 75.3 9.34 17.5 144.80000000000001 16.07 15123 2012-01-07T17:00:00.000 RAW -2.2559999999999998 -2.2559999999999998 -3.492 0 0 3 75.2 9.3800000000000008 17.88 146 13.9 15123 2012-01-07T18:00:00.000 ST -2.0939999999999999 -2.0939999999999999 -3.492 0 0 3 74.7 9.6999999999999993 23.55 145.30000000000001 17.5 15123 2012-01-07T19:00:00.000 RAW -1.905 -1.905 -2.0939999999999999 0 0 0 74.3 8.81 22.54 148 23.57 15123 2012-01-07T20:00:00.000 RAW -1.4870000000000001 -1.4870000000000001 -2.0939999999999999 0 0 0 74.400000000000006 8.34 17.940000000000001 147.9 14.33 15123 2012-01-07T21:00:00.000 RAW -1.175 -1.2130000000000001 -2.0939999999999999 0 0 0 74.400000000000006 9.44 16.87 146.5 15.68 15123 2012-01-07T22:00:00.000 RAW -1.175 -1.232 -2.0939999999999999 0 0 0 74 9.41 17.63 145 14.42 15123 2012-01-07T23:00:00.000 RAW -0.60699999999999998 -0.65500000000000003 -2.0939999999999999 0 0 0 73.900000000000006 10.66 21.47 149.5 19.05 15123 2012-01-08T00:00:00.000 RAW -0.48499999999999999 -0.56000000000000005 -2.0939999999999999 0 0 0 73.400000000000006 9.35 19.010000000000002 144.30000000000001 21.36 15123 2012-01-08T01:00:00.000 RAW -0.48499999999999999 -0.73099999999999998 -2.0939999999999999 0 0 0 73.400000000000006 10.83 21.34 151.30000000000001 18.52 15123 2012-01-08T02:00:00.000 RAW -0.48499999999999999 -0.56000000000000005 -2.0939999999999999 0 0 0 73.3 10.75 22.09 146.30000000000001 18.07 15123 2012-01-08T03:00:00.000 RAW -0.41899999999999998 -0.41899999999999998 -2.0939999999999999 0 0 0 72.900000000000006 9.92 20.27 142.30000000000001 17.850000000000001 15123 2012-01-08T04:00:00.000 RAW -0.38100000000000001 -0.46600000000000003 -2.0939999999999999 0 0 0 73.099999999999994 10.61 22.35 140.1 21.3 15123 2012-01-08T05:00:00.000 RAW -0.38100000000000001 -0.438 -2.0939999999999999 0 0 0 73.099999999999994 11.32 25.12 144.1 24.39 15123 2012-01-08T06:00:00.000 ST -0.25800000000000001 -0.29599999999999999 -2.0939999999999999 0 0 0 72.5 12.42 22.03 143.4 15.94 15123 2012-01-08T07:00:00.000 RAW -0.17299999999999999 -0.17299999999999999 -0.30499999999999999 0 0 0.1 72.900000000000006 11.13 23.16 143 14.75 15123 2012-01-08T08:00:00.000 RAW -0.14399999999999999 -0.17299999999999999 -0.30499999999999999 0 0 1 73 13.05 26.44 141 15.08 15123 2012-01-08T09:00:00.000 RAW 0.158 0.158 -0.30499999999999999 0 0 2 74.400000000000006 12.41 22.41 141.6 14.9 15123 2012-01-08T10:00:00.000 RAW 0.50800000000000001 0.48899999999999999 -0.30499999999999999 0 0 2 74.2 10.01 19.829999999999998 144.30000000000001 14.19 15123 2012-01-08T11:00:00.000 RAW 0.94299999999999995 0.877 -0.30499999999999999 0 0 2 73.099999999999994 12.64 23.73 148.19999999999999 15.21 15123 2012-01-08T12:00:00.000 RAW 1.454 1.454 -0.30499999999999999 0 0 2 74.099999999999994 12.37 24.23 145.9 16.059999999999999 15123 2012-01-08T13:00:00.000 RAW 2.0779999999999998 1.974 -0.30499999999999999 0 0 2 73.400000000000006 10 20.27 145.4 16.559999999999999 15123 2012-01-08T14:00:00.000 RAW 2.0779999999999998 1.5860000000000001 -0.30499999999999999 0 0 2 73.3 11.71 23.79 142.69999999999999 17.59 15123 2012-01-08T15:00:00.000 RAW 2.0779999999999998 1.7649999999999999 -0.30499999999999999 0 0 2 72.900000000000006 10.95 30.21 144.5 19.04 15123 2012-01-08T16:00:00.000 RAW 2.0779999999999998 1.746 -0.30499999999999999 0 0 2 73.2 11.34 24.92 144.6 19.61 15123 2012-01-08T17:00:00.000 RAW 2.1349999999999998 2.1349999999999998 -0.30499999999999999 0 0 2 73 9.8699999999999992 19.89 140.30000000000001 16.18 15123 2012-01-08T18:00:00.000 ST 2.4950000000000001 2.4380000000000002 -0.30499999999999999 0 0 2 72.8 7.69 18.25 140.5 15.23 15123 2012-01-08T19:00:00.000 RAW 2.4380000000000002 2.145 2.097 0 0 0 72.3 9.23 19.260000000000002 148.69999999999999 17 15123 2012-01-08T20:00:00.000 RAW 2.4380000000000002 2.23 2.097 0 0 0 72.099999999999994 7.7 18.309999999999999 144.9 13.93 15123 2012-01-08T21:00:00.000 RAW 2.4380000000000002 2.1160000000000001 2.097 0 0 0 72 8.08 23.41 140.5 15.25 15123 2012-01-08T22:00:00.000 RAW 2.4380000000000002 2.23 2.097 0 0 0 71.599999999999994 8.56 17.62 138.1 16.760000000000002 15123 2012-01-08T23:00:00.000 RAW 2.6 2.6 2.097 0 0 0 71.599999999999994 7.99 15.67 140.69999999999999 15.51 15123 2012-01-09T00:00:00.000 RAW 2.637 2.419 2.097 0 0 0 71.099999999999994 8.75 18.559999999999999 150.9 19.309999999999999 15123 2012-01-09T01:00:00.000 RAW 2.637 2.0030000000000001 1.9550000000000001 0 0 0 71.099999999999994 10.51 25.3 150.5 24.83 15123 2012-01-09T02:00:00.000 RAW 2.637 2.258 1.917 0 0 0 71.099999999999994 10.77 22.59 143.1 19.600000000000001 15123 2012-01-09T03:00:00.000 RAW 2.637 2.125 1.917 0 0 0 69.86 9.2200000000000006 21.4 147.1 19.87 15123 2012-01-09T04:00:00.000 RAW 2.637 1.87 1.86 0 0 0 69.08 9.73 23.35 138 28.25 15123 2012-01-09T05:00:00.000 RAW 2.637 1.9830000000000001 1.8320000000000001 0 0 0 68.989999999999995 10.97 31.47 140.4 26.08 15123 2012-01-09T06:00:00.000 ST 2.637 1.9079999999999999 1.8320000000000001 0 0 0 69.52 11.15 28.32 141.80000000000001 23.94 15123 2012-01-09T07:00:00.000 RAW 1.974 1.946 1.9079999999999999 0 0 0 68.510000000000005 11.24 22.91 144.19999999999999 17.96 15123 2012-01-09T08:00:00.000 RAW 1.9930000000000001 1.879 1.879 0 0 0 69.489999999999995 10.61 21.46 144.19999999999999 21.24 15123 2012-01-09T09:00:00.000 RAW 1.9930000000000001 1.8979999999999999 1.8320000000000001 0 0 0 69.34 10.87 27 148.1 20.3 15123 2012-01-09T10:00:00.000 RAW 2.3439999999999999 2.3340000000000001 1.8320000000000001 0 0 0 68.78 7.29 17.5 142.69999999999999 16.16 15123 2012-01-09T11:00:00.000 RAW 2.7890000000000001 2.7890000000000001 1.8320000000000001 0 0 1 69.92 7.73 16.68 147.30000000000001 15.95 15123 2012-01-09T12:00:00.000 RAW 2.9969999999999999 2.6179999999999999 1.8320000000000001 0 0 1 69.400000000000006 6.6390000000000002 16.8 142.1 15.75 15123 2012-01-09T13:00:00.000 RAW 2.9969999999999999 2.665 1.8320000000000001 0 0 1 69.430000000000007 8.9499999999999993 24.1 142.30000000000001 21.74 15123 2012-01-09T14:00:00.000 RAW 2.9969999999999999 2.5219999999999998 1.8320000000000001 0 0 1 69.08 9.5 21.33 151.30000000000001 20.51 15123 2012-01-09T15:00:00.000 RAW 2.9969999999999999 2.1909999999999998 1.8320000000000001 0 0 1 68.97 10.75 27.56 154.19999999999999 22.86 15123 2012-01-09T16:00:00.000 RAW 2.9969999999999999 1.841 1.8320000000000001 0 0 1 68.95 9.14 19.07 160.19999999999999 21.34 15123 2012-01-09T17:00:00.000 RAW 2.9969999999999999 1.633 1.633 0 0 1 68.69 12.41 33.159999999999997 166.6 24.31 15123 2012-01-09T18:00:00.000 ST 2.9969999999999999 1.5389999999999999 1.5389999999999999 0 0 1 68.47 13.32 28.69 168.1 23.24 15123 2012-01-09T19:00:00.000 RAW 1.5580000000000001 1.34 1.3109999999999999 0 0 0 68.34 11.01 25.24 156 28.15 15123 2012-01-09T20:00:00.000 RAW 1.5580000000000001 1.0089999999999999 1.0089999999999999 0 0 0 68.069999999999993 12.63 29.52 154.5 31.27 15123 2012-01-09T21:00:00.000 RAW 1.5580000000000001 0.71599999999999997 0.70599999999999996 0 0 0 67.95 14.58 39.270000000000003 157.30000000000001 29.57 15123 2012-01-09T22:00:00.000 RAW 1.5580000000000001 0.47 0.46 0 0 0 67.97 12.36 33.229999999999997 166.9 24.35 15123 2012-01-09T23:00:00.000 RAW 1.5580000000000001 -0.13500000000000001 -0.13500000000000001 0 0 0 67.97 7.59 21.46 155.5 26.41 15123 2012-01-10T00:00:00.000 RAW 1.5580000000000001 -0.39 -0.4 0 0 0 67.790000000000006 10.35 29.39 155.80000000000001 26.44 15123 2012-01-10T01:00:00.000 RAW 1.5580000000000001 -0.85399999999999998 -0.88200000000000001 0 0 0 67.95 7.64 19.45 141.69999999999999 22.02 15123 2012-01-10T02:00:00.000 RAW 1.5580000000000001 -1.46 -1.498 0 0 0 68.040000000000006 10.38 25.18 147.5 25.26 15123 2012-01-10T03:00:00.000 RAW 1.5580000000000001 -2.1419999999999999 -2.1520000000000001 0 0 0 67.92 11.46 28.7 146.9 25.08 15123 2012-01-10T04:00:00.000 RAW 1.5580000000000001 -2.6459999999999999 -2.6739999999999999 0 0 0 68 11.22 23.16 144.69999999999999 23.94 15123 2012-01-10T05:00:00.000 RAW 1.5580000000000001 -2.6259999999999999 -2.6930000000000001 0 0 0 67.97 2.5830000000000002 14.04 144.30000000000001 18.46 15123 2012-01-10T06:00:00.000 ST 1.5580000000000001 -3.2730000000000001 -3.2829999999999999 0 0 1 68.83 4.0540000000000003 24.43 22.99 37.85 15123 2012-01-10T07:00:00.000 RAW -3.2730000000000001 -4.7089999999999996 -4.7279999999999998 0 0 0 67.069999999999993 13.93 39.659999999999997 10.51 27.46 15123 2012-01-10T08:00:00.000 RAW -3.2730000000000001 -5.5179999999999998 -5.5179999999999998 0 0 0 67.400000000000006 15.02 31.92 8.81 27.59 15123 2012-01-10T09:00:00.000 RAW -3.2730000000000001 -5.8179999999999996 -5.8179999999999996 0 0 0 67.88 15.49 35.200000000000003 2.1379999999999999 28.7 15123 2012-01-10T10:00:00.000 RAW -3.2730000000000001 -5.8849999999999998 -6.0220000000000002 0 0 0 68.150000000000006 14.94 28.97 4.41 27.54 15123 2012-01-10T11:00:00.000 RAW -3.2730000000000001 -6.3920000000000003 -6.3920000000000003 0 0 0 68.459999999999994 12.4 29.98 6.51 29.92 15123 2012-01-10T12:00:00.000 RAW -3.2730000000000001 -4.5730000000000004 -6.577 0 0 0 67.91 7.6 18.77 11.49 23.99 15123 2012-01-10T13:00:00.000 RAW -3.2730000000000001 -4.7110000000000003 -6.577 0 0 0 68.33 5.2039999999999997 20.53 352.2 30.47 15123 2012-01-10T14:00:00.000 RAW -3.2730000000000001 -4.1159999999999997 -6.577 0 0 0 68.39 8.4700000000000006 22.15 332.8 28.24 15123 2012-01-10T15:00:00.000 RAW -3.2730000000000001 -4.6520000000000001 -6.577 0 0 0.1 68.760000000000005 2.2469999999999999 19.13 335.7 19.149999999999999 15123 2012-01-10T16:00:00.000 RAW -3.2730000000000001 -5.8970000000000002 -6.577 0 0 1 68.849999999999994 1.778 13.47 1.333 26.05 15123 2012-01-10T17:00:00.000 RAW -3.2730000000000001 -7.11 -7.11 0 0 1 68.88 2 10.7 29.74 12.48 15123 2012-01-10T18:00:00.000 ST -3.2730000000000001 -7.48 -7.59 0 0 1 69.12 0.84799999999999998 5.8579999999999997 38.44 15.18 15123 2012-01-10T19:00:00.000 RAW -7.19 -7.3 -7.51 0 0 0 69.2 1.2050000000000001 8.5 40.74 13.6 15123 2012-01-10T20:00:00.000 RAW -7.19 -7.56 -7.63 0 0 0 69.19 2.202 9.32 30.35 16.649999999999999 15123 2012-01-10T21:00:00.000 RAW -7.19 -7.58 -7.8 0 0 0 68.92 4.1020000000000003 14.49 74.099999999999994 21.56 15123 2012-01-10T22:00:00.000 RAW -7.19 -7.81 -7.81 0 0 0 69.06 3.2189999999999999 14.05 76.599999999999994 12.13 15123 2012-01-10T23:00:00.000 RAW -7.19 -8.1300000000000008 -8.2799999999999994 0 0 1 69.34 0.22800000000000001 6.4889999999999999 64.89 8.0399999999999991 15123 2012-01-11T00:00:00.000 RAW -7.19 -7.99 -8.2799999999999994 0 0 1 68.900000000000006 1.413 6.4260000000000002 23 10.49 15123 2012-01-11T01:00:00.000 RAW -7.19 -8.31 -8.5 0 0 1 68.959999999999994 3.3140000000000001 9.26 22.68 13.78 15123 2012-01-11T02:00:00.000 RAW -7.19 -8.44 -8.5 0 0 1 68.95 2.5819999999999999 8.3800000000000008 28.24 15.16 15123 2012-01-11T03:00:00.000 RAW -7.19 -9.09 -9.09 0 0 1 69.08 3.2130000000000001 11.15 20.77 18.96 15123 2012-01-11T04:00:00.000 RAW -7.19 -9.41 -9.42 0 0 1 69.02 2.8279999999999998 8.57 18.190000000000001 13.08 15123 2012-01-11T05:00:00.000 RAW -7.19 -10.07 -10.09 0 0 1 69.040000000000006 2.9430000000000001 8.1300000000000008 20.29 18.190000000000001 15123 2012-01-11T06:00:00.000 ST -7.19 -10.18 -10.18 0 0 1 68.72 3.9489999999999998 13.99 8.98 23.26 15123 2012-01-11T07:00:00.000 RAW -10.18 -10.72 -10.73 0 0 0.1 68.92 2.718 11.78 12.05 22.43 15123 2012-01-11T08:00:00.000 RAW -10.18 -10.77 -10.92 0 0 0 68.84 2.7730000000000001 8.51 14.07 24.09 15123 2012-01-11T09:00:00.000 RAW -10.18 -10.48 -10.92 0 0 0.1 68.87 3.1779999999999999 11.79 9.6199999999999992 28.48 15123 2012-01-11T10:00:00.000 RAW -9.89 -9.89 -10.92 0 0 0 68.58 4.97 11.53 6.7160000000000002 27.04 15123 2012-01-11T11:00:00.000 RAW -9.2899999999999991 -9.2899999999999991 -10.92 0 0 0.1 68.8 6.3 15.56 4.4050000000000002 24.23 15123 2012-01-11T12:00:00.000 RAW -6.6050000000000004 -6.6050000000000004 -10.92 0 0 0 68.31 5.1980000000000004 14.3 6.7439999999999998 28.12 15123 2012-01-11T13:00:00.000 RAW -6.6050000000000004 -7.47 -10.92 0 0 0.1 68.63 4.4029999999999996 13.35 4.3360000000000003 29.06 15123 2012-01-11T14:00:00.000 RAW -6.6050000000000004 -7.29 -10.92 0 0 0.1 68.67 4.2389999999999999 14.92 11.64 25.79 15123 2012-01-11T15:00:00.000 RAW -6.6050000000000004 -7.29 -10.92 0 0 1 68.709999999999994 5.22 19.010000000000002 0.22700000000000001 36.57 15123 2012-01-11T16:00:00.000 RAW -6.6050000000000004 -7.89 -10.92 0 0 1 68.67 4.7130000000000001 12.84 6.9950000000000001 28.8 15123 2012-01-11T17:00:00.000 RAW -6.6050000000000004 -8.4600000000000009 -10.92 0 0 1 68.94 4.63 15.56 16.59 31.71 15123 2012-01-11T18:00:00.000 ST -6.6050000000000004 -9.35 -10.92 0 0 1 68.52 6.1289999999999996 19.72 9.26 27.79 15123 2012-01-11T19:00:00.000 RAW -9.08 -9.33 -9.8699999999999992 0 0 0.1 68.819999999999993 9.44 24.63 13.82 25.8 15123 2012-01-11T20:00:00.000 RAW -8.8800000000000008 -9.39 -9.8699999999999992 0 0 0 68.510000000000005 14.85 33.71 17.920000000000002 24.9 15123 2012-01-11T21:00:00.000 RAW -8.8699999999999992 -9.0299999999999994 -9.8699999999999992 0 0 0 68.59 14.35 36.549999999999997 16.989999999999998 26.57 15123 2012-01-11T22:00:00.000 RAW -8.77 -9.8699999999999992 -9.8699999999999992 0 0 0.1 68.58 12.33 27.41 12.12 24.58 15123 2012-01-11T23:00:00.000 RAW -8.77 -10.26 -10.26 0 0 0 68.38 9.1199999999999992 20.420000000000002 10.35 27.64 15123 2012-01-12T00:00:00.000 RAW -8.77 -10.48 -10.67 0 0 0.1 68.459999999999994 8.4700000000000006 18.59 16.14 17.22 15123 2012-01-12T01:00:00.000 RAW -8.77 -10.69 -10.7 0 0 0.1 68.5 7.78 14.11 12.64 21.86 15123 2012-01-12T02:00:00.000 RAW -8.77 -9.91 -10.7 0 0 0 68.150000000000006 7.73 15.82 12.55 25.17 15123 2012-01-12T03:00:00.000 RAW -8.77 -10.38 -10.7 0 0 0.1 68.36 6.085 14.31 12.1 25.59 15123 2012-01-12T04:00:00.000 RAW -8.77 -9.4499999999999993 -10.7 0 0 0.1 68.27 8.1 15.31 20.48 14.57 15123 2012-01-12T05:00:00.000 RAW -8.77 -9.09 -10.7 0 0 0.1 68.290000000000006 6.4859999999999998 16.39 23.19 19.13 15123 2012-01-12T06:00:00.000 ST -8.58 -8.58 -10.7 0 0 1 68.400000000000006 2.9020000000000001 9.4499999999999993 23.08 20.43 15123 2012-01-12T07:00:00.000 RAW -7.6 -8.07 -8.81 0 0 0 68.13 4.133 15.44 18.149999999999999 29.52 15123 2012-01-12T08:00:00.000 RAW -7.45 -7.45 -8.81 0 0 0 68.38 1.1459999999999999 8.19 10.09 20.29 15123 2012-01-12T09:00:00.000 RAW -6.6929999999999996 -6.6929999999999996 -8.81 0 0 0.1 68.58 0.40699999999999997 8.25 323.39999999999998 5.492 15123 2012-01-12T10:00:00.000 RAW -5.4969999999999999 -5.4969999999999999 -8.81 0 0 0.1 68.66 0.54600000000000004 9.6999999999999993 8.09 25.03 15123 2012-01-12T11:00:00.000 RAW -4.63 -4.6680000000000001 -8.81 0 0 1 68.64 1E-3 6.3E-2 20.05 0.19900000000000001 15123 2012-01-12T12:00:00.000 RAW -4.2469999999999999 -4.2469999999999999 -8.81 0 0 1 68.75 0 0 0 0 15123 2012-01-12T13:00:00.000 RAW -3.387 -3.387 -8.81 0 0 1 68.849999999999994 0 0 0 0 15123 2012-01-12T14:00:00.000 RAW -1.7529999999999999 -1.7529999999999999 -8.81 0 0 1 68.47 0 0 0 0 15123 2012-01-12T15:00:00.000 RAW -1.08 -2.0099999999999998 -8.81 0 0 1 68.75 1E-3 0.252 175.2 0.61299999999999999 15123 2012-01-12T16:00:00.000 RAW -1.08 -3.1309999999999998 -8.81 0 0 1 68.989999999999995 0 0 0 0 15123 2012-01-12T17:00:00.000 RAW -1.08 -3.35 -8.81 0 0 2 69.400000000000006 5.8999999999999997E-2 2.6440000000000001 256.10000000000002 0.28000000000000003 15123 2012-01-12T18:00:00.000 ST -1.08 -2.9780000000000002 -8.81 0 0 2 69.72 0.39700000000000002 7.43 197.8 15.09 15123 2012-01-12T19:00:00.000 RAW -1.4870000000000001 -1.4870000000000001 -2.9780000000000002 0 0 0 68.55 6.4509999999999996 23.29 162 14.67 15123 2012-01-12T20:00:00.000 RAW -1.1459999999999999 -1.383 -2.9780000000000002 0 0 0 68.650000000000006 7.17 25.88 154.9 33.75 15123 2012-01-12T21:00:00.000 RAW -0.67200000000000004 -2.113 -2.9780000000000002 0 0 0 68.78 5.0339999999999998 19.010000000000002 150.80000000000001 19.690000000000001 15123 2012-01-12T22:00:00.000 RAW -0.67200000000000004 -0.97499999999999998 -2.9780000000000002 0 0 0 69.209999999999994 4.3639999999999999 18.07 154 12.49 15123 2012-01-12T23:00:00.000 RAW -0.67200000000000004 -1.5249999999999999 -2.9780000000000002 0 0 0 68.59 9.7100000000000009 23.04 148.6 18.73 15123 2012-01-13T00:00:00.000 RAW -0.67200000000000004 -1.222 -2.9780000000000002 0 0 0 68.569999999999993 12.45 25.12 135.30000000000001 20.350000000000001 15123 2012-01-13T01:00:00.000 RAW -0.67200000000000004 -1.335 -2.9780000000000002 0 0 0 68.72 10.63 24.81 133.1 19.559999999999999 15123 2012-01-13T02:00:00.000 RAW -0.67200000000000004 -1.458 -2.9780000000000002 0 0 0 68.62 9.07 21.59 133.1 20.66 15123 2012-01-13T03:00:00.000 RAW -0.67200000000000004 -2.8820000000000001 -3.149 0 0 0 68.900000000000006 5.1420000000000003 18.57 154.19999999999999 18.45 15123 2012-01-13T04:00:00.000 RAW -0.67200000000000004 -4.0369999999999999 -4.0369999999999999 0 0 0 68.87 7.95 16.309999999999999 167.9 16.73 15123 2012-01-13T05:00:00.000 RAW -0.67200000000000004 -4.9290000000000003 -4.9580000000000002 0 0 0 69.09 5.7480000000000002 17.63 177.3 19.190000000000001 15123 2012-01-13T06:00:00.000 ST -0.67200000000000004 -5.6040000000000001 -5.6040000000000001 0 0 0 68.819999999999993 5.4279999999999999 16.690000000000001 175.2 13.34 15123 2012-01-13T07:00:00.000 RAW -5.6040000000000001 -6.3520000000000003 -6.5670000000000002 0 0 1 69.38 1.8919999999999999 10.58 180.9 5.0759999999999996 15123 2012-01-13T08:00:00.000 RAW -5.6040000000000001 -6.391 -6.8010000000000002 0 0 1 69.489999999999995 2.4E-2 1.071 180.7 0.48199999999999998 15123 2012-01-13T09:00:00.000 RAW -5.6040000000000001 -5.7389999999999999 -6.8010000000000002 0 0 1 69.59 0 6.3E-2 181.2 1E-3 15123 2012-01-13T10:00:00.000 RAW -3.9590000000000001 -3.9590000000000001 -6.8010000000000002 0 0 1 68.61 0 0 0 0 15123 2012-01-13T11:00:00.000 RAW -2.6349999999999998 -2.73 -6.8010000000000002 0 0 1 68.44 0 0.189 244.4 5.0999999999999997E-2 15123 2012-01-13T12:00:00.000 RAW -1.8859999999999999 -1.8859999999999999 -6.8010000000000002 0 0 1 68.45 0 0 0 0 15123 2012-01-13T13:00:00.000 RAW -0.40899999999999997 -0.85499999999999998 -6.8010000000000002 0 0 1 68.489999999999995 0 6.3E-2 349.3 0 15123 2012-01-13T14:00:00.000 RAW -0.40899999999999997 -0.81799999999999995 -6.8010000000000002 0 0 1 69 0 0 0 0 15123 2012-01-13T15:00:00.000 RAW -0.33500000000000002 -0.33500000000000002 -6.8010000000000002 0 0 1 69.180000000000007 0 0 0 0 15123 2012-01-13T16:00:00.000 RAW 3.4000000000000002E-2 -1.262 -6.8010000000000002 0 0 1 68.91 0 0 0 0 15123 2012-01-13T17:00:00.000 RAW 3.4000000000000002E-2 -2.0960000000000001 -6.8010000000000002 0 0 1 69.27 8.0000000000000002E-3 0.755 182.6 1.4410000000000001 15123 2012-01-13T18:00:00.000 ST 3.4000000000000002E-2 -1.8380000000000001 -6.8010000000000002 0 0 1 69.05 3.0000000000000001E-3 0.441 229.6 1.9630000000000001 15123 2012-01-13T19:00:00.000 RAW -1.649 -1.724 -1.8859999999999999 0 0 0 68.66 1.7000000000000001E-2 1.385 111 1.59 15123 2012-01-13T20:00:00.000 RAW -1.649 -1.9139999999999999 -2.1320000000000001 0 0 0 68.39 0.16900000000000001 3.84 181.5 7.52 15123 2012-01-13T21:00:00.000 RAW -0.85299999999999998 -1.0329999999999999 -2.1320000000000001 0 0 0 68.56 4.82 16.68 161.1 18.989999999999998 15123 2012-01-13T22:00:00.000 RAW -0.85299999999999998 -1.81 -2.1320000000000001 0 0 0 68.459999999999994 11.01 23.8 153.19999999999999 20.239999999999998 15123 2012-01-13T23:00:00.000 RAW -0.85299999999999998 -2.294 -2.294 0 0 0 68.73 11.06 25.62 150.9 26.67 15123 2012-01-14T00:00:00.000 RAW -0.85299999999999998 -2.5979999999999999 -2.6259999999999999 0 0 0 67.36 9.7899999999999991 24.24 147.4 21.9 15123 2012-01-14T01:00:00.000 RAW -0.85299999999999998 -2.6349999999999998 -2.6360000000000001 0 0 1 69.540000000000006 10.56 26.88 147.5 23.73 15123 2012-01-14T02:00:00.000 RAW -0.85299999999999998 -2.6360000000000001 -2.6640000000000001 0 0 2 70.5 8.6300000000000008 22.92 148.30000000000001 26.67 15123 2012-01-14T03:00:00.000 RAW -0.85299999999999998 -2.8159999999999998 -2.8639999999999999 0 0 3 71.400000000000006 10.18 22.1 149.9 28.31 15123 2012-01-14T04:00:00.000 RAW -0.85299999999999998 -2.8159999999999998 -2.8639999999999999 0 0 3 69.349999999999994 10.44 24.87 145.5 28.1 15123 2012-01-14T05:00:00.000 RAW -0.85299999999999998 -3.073 -3.073 0 0 5 72.8 8.2200000000000006 18.510000000000002 151.30000000000001 24.39 15123 2012-01-14T06:00:00.000 ST -0.85299999999999998 -3.1680000000000001 -3.1680000000000001 0 0 7 74.400000000000006 9.39 20.59 152.1 20.95 15123 2012-01-14T07:00:00.000 RAW -3.14 -3.4260000000000002 -3.4260000000000002 0 0 0 74.3 9.09 20.9 152 20.010000000000002 15123 2012-01-14T08:00:00.000 RAW -3.14 -3.6070000000000002 -3.6829999999999998 0 0 10.84 23.11 143.69999999999999 21.77 15123 2012-01-14T09:00:00.000 RAW -3.14 -3.4540000000000002 -3.6829999999999998 0 0 1 75 7.15 19.27 138.5 20.94 15123 2012-01-14T10:00:00.000 RAW -3.14 -3.3010000000000002 -3.6829999999999998 0 0 4 77.5 6.8449999999999998 17.38 143.30000000000001 19.79 15123 2012-01-14T11:00:00.000 RAW -2.883 -2.883 -3.6829999999999998 0 0 5 78.8 7.54 18.57 150.30000000000001 22.29 15123 2012-01-14T12:00:00.000 RAW -2.835 -3.2349999999999999 -3.6829999999999998 0 0 7 80.7 9.31 22.92 151.4 26.37 15123 2012-01-14T13:00:00.000 RAW -2.835 -3.6259999999999999 -3.6829999999999998 0 0 10 83.2 12.54 34.380000000000003 157.30000000000001 28.27 15123 2012-01-14T14:00:00.000 RAW -2.835 -4.3150000000000004 -4.3150000000000004 0 0 10 82.9 13.75 35.130000000000003 159.9 27.78 15123 2012-01-14T15:00:00.000 RAW -2.835 -5.1710000000000003 -5.1710000000000003 0 0 10 82.5 13.74 36.26 168.4 25.97 15123 2012-01-14T16:00:00.000 RAW -2.835 -5.8860000000000001 -5.8860000000000001 0 0 11 83.2 10.95 27.51 155.5 23.34 15123 2012-01-14T17:00:00.000 RAW -2.835 -6.47 -6.4889999999999999 0 0 11 82.5 10.69 21.66 151.5 20.260000000000002 15123 2012-01-14T18:00:00.000 ST -2.835 -6.782 -7.12 0 0 11 79.900000000000006 7.42 23.68 165.1 27.12 15123 2012-01-14T19:00:00.000 RAW -6.508 -6.5570000000000004 -6.782 0 0 2 81.400000000000006 6.7990000000000004 19.71 161 16.829999999999998 15123 2012-01-14T20:00:00.000 RAW -6.4790000000000001 -6.9089999999999998 -6.9089999999999998 0 0 2 79.7 8.64 22.86 162.19999999999999 21.29 15123 2012-01-14T21:00:00.000 RAW -6.4790000000000001 -7.47 -7.48 0 0 2 79.599999999999994 5.6820000000000004 14.61 156.5 15.51 15123 2012-01-14T22:00:00.000 RAW -6.4790000000000001 -7.64 -7.79 0 0 2 78.8 4.165 10.65 158.80000000000001 11.56 15123 2012-01-14T23:00:00.000 RAW -6.4790000000000001 -7.13 -7.79 0 0 3.4820000000000002 10.9 148.9 9.83 15123 2012-01-15T00:00:00.000 RAW -6.4790000000000001 -7.23 -7.79 0 0 2.7149999999999999 11.4 145.1 14.87 15123 2012-01-15T01:00:00.000 RAW -6.4790000000000001 -7.59 -7.79 0 0 4 82.6 4.0090000000000003 16.13 155.4 13.52 15123 2012-01-15T02:00:00.000 RAW -6.4790000000000001 -8.17 -8.32 0 0 4 82.6 2.6019999999999999 10.33 154.5 9.0399999999999991 15123 2012-01-15T03:00:00.000 RAW -6.4790000000000001 -7.66 -8.32 0 0 5 82.5 0.43099999999999999 4.41 159.9 8.57 15123 2012-01-15T04:00:00.000 RAW -6.4790000000000001 -7.67 -8.32 0 0 5 81.900000000000006 0.36499999999999999 4.2210000000000001 161 7.77 15123 2012-01-15T05:00:00.000 RAW -6.4790000000000001 -7.67 -8.32 0 0 5 81.7 8.8999999999999996E-2 1.764 153.5 6.5670000000000002 15123 2012-01-15T06:00:00.000 ST -6.4790000000000001 -7.6 -8.32 0 0 5 82.4 0.93100000000000005 7.06 149.30000000000001 10.61 15123 2012-01-15T07:00:00.000 RAW -7.55 -7.76 -7.76 0 0 0 82.1 0.34200000000000003 8.06 158.1 7.2 15123 2012-01-15T08:00:00.000 RAW -7.55 -8.16 -8.16 0 0 0.1 82.6 0 0 0 0 15123 2012-01-15T09:00:00.000 RAW -7.55 -7.67 -8.23 0 0 0 81.2 0 0 0 0 15123 2012-01-15T10:00:00.000 RAW -7.22 -7.41 -8.23 0 0 0 77.5 0 0 0 0 15123 2012-01-15T11:00:00.000 RAW -6.7030000000000003 -6.7030000000000003 -8.23 0 0 0 79.400000000000006 0 0 0 0 15123 2012-01-15T12:00:00.000 RAW -6.6449999999999996 -7.95 -8.23 0 0 0 80.2 0.35199999999999998 6.6760000000000002 27.01 11.32 15123 2012-01-15T13:00:00.000 RAW -6.6449999999999996 -8.08 -8.4 0 0 0 80.599999999999994 3.8029999999999999 10.9 27.74 21.73 15123 2012-01-15T14:00:00.000 RAW -6.6449999999999996 -8.7799999999999994 -8.81 0 0 0 81.2 4.8849999999999998 13.98 24.38 27.35 15123 2012-01-15T15:00:00.000 RAW -6.6449999999999996 -9.6 -9.6 0 0 0 78 8.56 18.2 26.33 25.83 15123 2012-01-15T16:00:00.000 RAW -6.6449999999999996 -11.16 -11.16 0 0 0 80.7 10.45 18.96 25 25.1 15123 2012-01-15T17:00:00.000 RAW -6.6449999999999996 -11.93 -11.93 0 0 0 80.400000000000006 8.77 18.14 17.93 24.45 15123 2012-01-15T18:00:00.000 ST -6.6449999999999996 -12.38 -12.39 0 0 0 80.599999999999994 8.23 17.260000000000002 16.46 25.02 15123 2012-01-15T19:00:00.000 RAW -12.36 -12.9 -12.9 0 0 0 80.599999999999994 8.08 18.09 17.27 23.36 15123 2012-01-15T20:00:00.000 RAW -12.36 -13.52 -13.53 0 0 0 80 8.93 25.71 15.57 22.56 15123 2012-01-15T21:00:00.000 RAW -12.36 -14.03 -14.03 0 0 1 81.099999999999994 7.68 20.170000000000002 17.350000000000001 26.41 15123 2012-01-15T22:00:00.000 RAW -12.36 -14.75 -14.77 0 0 1 81.400000000000006 11.3 20.61 24.74 21.49 15123 2012-01-15T23:00:00.000 RAW -12.36 -15.06 -15.06 0 0 1 81.2 11.03 19.61 27.99 24.12 15123 2012-01-16T00:00:00.000 RAW -12.36 -15.29 -15.29 0 0 1 80.5 10.24 22.88 30.53 23.24 15123 2012-01-16T01:00:00.000 RAW -12.36 -15.49 -15.49 0 0 1 80.5 8.3699999999999992 16.96 30.04 23.65 15123 2012-01-16T02:00:00.000 RAW -12.36 -15.61 -15.63 0 0 1 80.3 6.8019999999999996 14.69 29.87 22.14 15123 2012-01-16T03:00:00.000 RAW -12.36 -15.74 -15.74 0 0 1 79.5 4.8239999999999998 12.92 32.81 19.68 15123 2012-01-16T04:00:00.000 RAW -12.36 -15.93 -16.02 0 0 1 78.8 2.5499999999999998 9.65 36.11 14.97 15123 2012-01-16T05:00:00.000 RAW -12.36 -16.3 -16.3 0 0 1 75.099999999999994 1.3759999999999999 7.06 20.56 9.14 15123 2012-01-16T06:00:00.000 ST -12.36 -16.43 -16.48 0 0 1 76 0.748 6.8719999999999999 27.79 7.01 15123 2012-01-16T07:00:00.000 RAW -16 -16.2 -16.46 0 0 2 77.599999999999994 0 0 0 0 15123 2012-01-16T08:00:00.000 RAW -16 -17.21 -17.239999999999998 0 0 4 79.7 1.359 12.11 27.69 14.48 15123 2012-01-16T09:00:00.000 RAW -16 -17.2 -17.47 0 0 4 78.099999999999994 6.79 18.47 30.12 24.7 15123 2012-01-16T10:00:00.000 RAW -16 -17.45 -17.5 0 0 7 83 10.199999999999999 24.02 21.12 26.53 15123 2012-01-16T11:00:00.000 RAW -16 -17.29 -17.5 0 0 7 80.5 7.78 21.12 17.07 29.66 15123 2012-01-16T12:00:00.000 RAW -16 -16.850000000000001 -17.5 0 0 8 83.5 7.53 25.22 12.17 29.76 15123 2012-01-16T13:00:00.000 RAW -16 -16.3 -17.5 0 0 8 80.5 7.42 25.16 16.04 25.08 15123 2012-01-16T14:00:00.000 RAW -16 -16.05 -17.5 0 0 9 83.8 5.64 17.02 9.85 27.83 15123 2012-01-16T15:00:00.000 RAW -15.57 -15.83 -17.5 0 0 9 83.7 2.8879999999999999 11.16 19.440000000000001 23.12 15123 2012-01-16T16:00:00.000 RAW -15.57 -16.55 -17.5 0 0 9 83.1 1.0840000000000001 11.6 23.45 23.87 15123 2012-01-16T17:00:00.000 RAW -15.57 -16.77 -17.5 0 0 9 83.7 6.1959999999999997 14.12 24.73 22.52 15123 2012-01-16T18:00:00.000 ST -15.57 -16.760000000000002 -17.5 0 0 9 83.8 7.28 17.53 15.72 21.99 15123 2012-01-16T19:00:00.000 RAW -16.75 -17.02 -17.02 0 0 0 82.4 6.3979999999999997 18.22 18.78 23.46 15123 2012-01-16T20:00:00.000 RAW -16.75 -17.37 -17.37 0 0 0 82.7 5.9139999999999997 14.12 19.46 23.33 15123 2012-01-16T21:00:00.000 RAW -16.75 -17.899999999999999 -17.899999999999999 0 0 0 82.6 9.02 19.55 19.309999999999999 26.79 15123 2012-01-16T22:00:00.000 RAW -16.75 -18.43 -18.43 0 0 0.1 83.7 8.17 22.26 15.23 26.14 15123 2012-01-16T23:00:00.000 RAW -16.75 -19.059999999999999 -19.059999999999999 0 0 0 83.1 10.039999999999999 23.84 17.420000000000002 26.61 15123 2012-01-17T00:00:00.000 RAW -16.75 -19.84 -19.850000000000001 0 0 2 85.4 11.03 23.46 13.88 28.11 15123 2012-01-17T01:00:00.000 RAW -16.75 -20.54 -20.56 0 0 3 86.2 11.11 28.89 13.39 26.37 15123 2012-01-17T02:00:00.000 RAW -16.75 -21.19 -21.19 0 0 3 85.9 11.31 25.67 7.86 25.54 15123 2012-01-17T03:00:00.000 RAW -16.75 -21.77 -21.77 0 0 5 87.2 10.15 21.89 9.5500000000000007 26.36 15123 2012-01-17T04:00:00.000 RAW -16.75 -22.27 -22.27 0 0 5 86.8 9.94 25.42 11.65 24.68 15123 2012-01-17T05:00:00.000 RAW -16.75 -22.64 -22.69 0 0 6 87.7 9.92 24.48 8.67 25 15123 2012-01-17T06:00:00.000 ST -16.75 -23.14 -23.14 0 0 6 86.9 9.7200000000000006 22.9 10.48 24.29 15123 2012-01-17T07:00:00.000 RAW -23.14 -23.59 -23.59 0 0 1 88.1 10.51 24.54 10.8 26.21 15123 2012-01-17T08:00:00.000 RAW -23.14 -23.9 -23.9 0 0 2 88.5 12.36 27.64 11.85 26.47 15123 2012-01-17T09:00:00.000 RAW -23.14 -23.87 -23.98 0 0 2 88.5 10.6 25.18 9.91 23.08 15123 2012-01-17T10:00:00.000 RAW -23.14 -23.59 -23.98 0 0 2 88.7 9.24 25.56 13.47 23.74 15123 2012-01-17T11:00:00.000 RAW -23.14 -23.45 -23.98 0 0 2 88.6 9.49 21.39 8.8699999999999992 24.01 15123 2012-01-17T12:00:00.000 RAW -22.6 -22.63 -23.98 0 0 3 88.5 9.68 21.77 9.8699999999999992 25.37 15123 2012-01-17T13:00:00.000 RAW -21.57 -21.68 -23.98 0 0 3 87.9 7.27 18.739999999999998 12.55 23.51 15123 2012-01-17T14:00:00.000 RAW -21.57 -22.29 -23.98 0 0 3 88.4 8.68 23.41 14.31 22.54 15123 2012-01-17T15:00:00.000 RAW -21.57 -22.63 -23.98 0 0 3 88.5 9.92 21.51 15.76 23.29 15123 2012-01-17T16:00:00.000 RAW -21.57 -23.04 -23.98 0 0 4 89.5 9.83 21.51 19.18 21.5 15123 2012-01-17T17:00:00.000 RAW -21.57 -23.37 -23.98 0 0 5 90.2 9.9700000000000006 24.42 20.71 21.79 15123 2012-01-17T18:00:00.000 ST -21.57 -23.53 -23.98 0 0 6 90.1 10.85 23.98 17.579999999999998 21.67 15123 2012-01-17T19:00:00.000 RAW -23.53 -23.67 -23.7 0 0 0.1 90.3 9.77 27.26 13.98 22.85 15123 2012-01-17T20:00:00.000 RAW -23.53 -23.75 -23.76 0 0 1 90.5 9.61 25.43 14.62 22.9 15123 2012-01-17T21:00:00.000 RAW -23.53 -24.06 -24.06 0 0 1 90.2 9.6999999999999993 22.09 15.04 21.12 15123 2012-01-17T22:00:00.000 RAW -23.53 -24.56 -24.56 0 0 1 90.2 8.7899999999999991 22.41 12.92 21.46 15123 2012-01-17T23:00:00.000 RAW -23.53 -24.7 -24.7 0 0 1 90.2 8.2799999999999994 18.3 10.039999999999999 23.38 15123 2012-01-18T00:00:00.000 RAW -23.53 -25.11 -25.11 0 0 1 89.9 9.67 23.8 9.24 23.23 15123 2012-01-18T01:00:00.000 RAW -23.53 -25.59 -25.59 0 0 1 89.9 10.34 24.05 10.42 23.23 15123 2012-01-18T02:00:00.000 RAW -23.53 -26.26 -26.28 0 0 1 89.7 11.84 21.53 12.06 23.95 15123 2012-01-18T03:00:00.000 RAW -23.53 -26.45 -26.5 0 0 1 89.6 10.92 22.22 13.07 22.72 15123 2012-01-18T04:00:00.000 RAW -23.53 -26.66 -26.66 0 0 1 89.1 11.4 23.17 13.37 20.85 15123 2012-01-18T05:00:00.000 RAW -23.53 -26.76 -26.8 0 0 1 89 9.73 19.57 11.96 20.23 15123 2012-01-18T06:00:00.000 ST -23.53 -26.71 -26.83 0 0 1 89.3 9.82 24.75 5.2619999999999996 22.52 15123 2012-01-18T07:00:00.000 RAW -26.64 -26.69 -26.76 0 0 0 89.1 8.59 22.98 5.4930000000000003 21.66 15123 2012-01-18T08:00:00.000 RAW -26.64 -26.69 -26.82 0 0 0 89 7.87 20.9 7.17 20.77 15123 2012-01-18T09:00:00.000 RAW -26.64 -26.66 -26.83 0 0 0 89.2 8.43 20.77 12.5 20.28 15123 2012-01-18T10:00:00.000 RAW -26.43 -26.45 -26.83 0 0 0.1 89.4 9.6 23.55 8.27 21.39 15123 2012-01-18T11:00:00.000 RAW -25.67 -25.67 -26.83 0 0 1 89.8 13.29 31.88 6.3040000000000003 21.75 15123 2012-01-18T12:00:00.000 RAW -25.11 -25.29 -26.83 0 0 1 90.2 11.1 32.450000000000003 4.492 23.36 15123 2012-01-18T13:00:00.000 RAW -24.96 -25.01 -26.83 0 0 1 90.1 11.85 24.3 1.103 23.4 15123 2012-01-18T14:00:00.000 RAW -24.19 -24.27 -26.83 0 0 5 93.3 12.31 35.79 358.5 23.3 15123 2012-01-18T15:00:00.000 RAW -24.17 -24.3 -26.83 0 0 6 94.3 11.59 33.07 15.65 20.62 15123 2012-01-18T16:00:00.000 RAW -24.17 -24.69 -26.83 0 0 7 95.1 11.95 30.48 11.37 24.46 15123 2012-01-18T17:00:00.000 RAW -24.17 -24.7 -26.83 0 0 7 94.9 11.6 33.380000000000003 12.56 22.31 15123 2012-01-18T18:00:00.000 ST -24.17 -24.6 -26.83 0 0 7 93.5 12.07 26.83 18.239999999999998 19.52 15123 2012-01-18T19:00:00.000 RAW -24.24 -24.24 -24.6 0 0 0 93.5 12.31 27.27 16.68 16.27 15123 2012-01-18T20:00:00.000 RAW -24.16 -24.22 -24.6 0 0 1 94.5 12.27 27.52 18.88 17.829999999999998 15123 2012-01-18T21:00:00.000 RAW -24.16 -24.33 -24.6 0 0 1 94.5 11.25 21.27 14.39 19.57 15123 2012-01-18T22:00:00.000 RAW -24.16 -24.32 -24.6 0 0 2 94.6 13.59 27.33 16.809999999999999 18.93 15123 2012-01-18T23:00:00.000 RAW -24.16 -24.41 -24.6 0 0 2 94.4 14.13 27.65 24.22 21.62 15123 2012-01-19T00:00:00.000 RAW -24.16 -24.35 -24.6 0 0 2 94.3 13.74 27.52 14.99 20.88 15123 2012-01-19T01:00:00.000 RAW -24.16 -24.48 -24.6 0 0 2 94.1 12.67 26.64 17.940000000000001 21.66 15123 2012-01-19T02:00:00.000 RAW -24.16 -24.52 -24.65 0 0 2 94.1 14.19 27.14 21.06 19.68 15123 2012-01-19T03:00:00.000 RAW -24.16 -24.65 -24.68 0 0 2 93.9 14.67 30.8 19.440000000000001 22.91 15123 2012-01-19T04:00:00.000 RAW -24.16 -24.57 -24.68 0 0 2 93.8 14.77 30.05 22.27 22.14 15123 2012-01-19T05:00:00.000 RAW -24.16 -24.57 -24.68 0 0 2 93.8 14.61 29.48 19.399999999999999 22.07 15123 2012-01-19T06:00:00.000 ST -24.16 -24.68 -24.68 0 0 2 93.7 13.57 31.18 13.87 23.36 15123 2012-01-19T07:00:00.000 RAW -24.6 -24.62 -24.77 0 0 0 93.6 13.63 32.76 15.3 21.99 15123 2012-01-19T08:00:00.000 RAW -24.43 -24.47 -24.77 0 0 0 93.5 13.63 29.29 17.3 23.41 15123 2012-01-19T09:00:00.000 RAW -24.36 -24.44 -24.77 0 0 0 93.3 15.46 31.94 17.54 22.04 15123 2012-01-19T10:00:00.000 RAW -23.97 -23.97 -24.77 0 0 0 93.2 14.67 34.840000000000003 14.78 25.17 15123 2012-01-19T11:00:00.000 RAW -22.94 -22.97 -24.77 0 0 0 92.9 14.65 30.74 16.75 22.82 15123 2012-01-19T12:00:00.000 RAW -22.27 -22.27 -24.77 0 0 0 92.6 14.82 33.76 15.58 24.76 15123 2012-01-19T13:00:00.000 RAW -21.05 -21.05 -24.77 0 0 0 92.3 13.07 25.87 15.37 25.14 15123 2012-01-19T14:00:00.000 RAW -20.53 -21.02 -24.77 0 0 0 92.2 13.3 25.42 10.01 25.59 15123 2012-01-19T15:00:00.000 RAW -20.53 -21.19 -24.77 0 0 0 92.3 12.32 27.37 12.02 26.31 15123 2012-01-19T16:00:00.000 RAW -20.53 -21.54 -24.77 0 0 0 92.5 14.54 30.72 13.48 24.84 15123 2012-01-19T17:00:00.000 RAW -20.53 -21.74 -24.77 0 0 0 92.5 15.86 36.78 16.57 24.45 15123 2012-01-19T18:00:00.000 ST -20.53 -21.78 -24.77 0 0 0 92.5 14.72 34.450000000000003 14.01 24.95 15123 2012-01-19T19:00:00.000 RAW -21.49 -21.75 -21.8 0 0 0 92.4 12.17 27.76 15.4 22.44 15123 2012-01-19T20:00:00.000 RAW -21.43 -21.52 -21.8 0 0 0 92.4 11.95 25.43 12.33 23.13 15123 2012-01-19T21:00:00.000 RAW -21.28 -21.38 -22.03 0 0 0 91.9 9.49 25.05 9.24 21.06 15123 2012-01-19T22:00:00.000 RAW -21.2 -21.38 -22.03 0 0 0 91.7 6.5259999999999998 17.350000000000001 2.798 24.43 15123 2012-01-19T23:00:00.000 RAW -21.09 -21.09 -22.03 0 0 0 91.7 4.7220000000000004 14.76 0.80600000000000005 20.5 15123 2012-01-20T00:00:00.000 RAW -20.170000000000002 -20.239999999999998 -22.03 0 0 0 91.5 3.5369999999999999 10.79 13.8 21.91 15123 2012-01-20T01:00:00.000 RAW -20.170000000000002 -20.28 -22.03 0 0 0 91.2 5.14 13.88 14.16 23.42 15123 2012-01-20T02:00:00.000 RAW -19.38 -19.38 -22.03 0 0 0 91.1 3.149 15.4 21.73 17.52 15123 2012-01-20T03:00:00.000 RAW -18.48 -18.48 -22.03 0 0 0 91 2.83 9.9700000000000006 19.399999999999999 18.37 15123 2012-01-20T04:00:00.000 RAW -18.2 -18.3 -22.03 0 0 0 90.7 6.1589999999999998 15.71 17.21 19.690000000000001 15123 2012-01-20T05:00:00.000 RAW -18.2 -18.7 -22.03 0 0 0 90.6 9.1 18.61 24.68 16.52 15123 2012-01-20T06:00:00.000 ST -17.8 -17.8 -22.03 0 0 0 91.3 6.0940000000000003 13.75 14.97 16.079999999999998 15123 2012-01-20T07:00:00.000 RAW -16.91 -16.920000000000002 -17.8 0 0 0 89.4 6.1479999999999997 16.399999999999999 19.78 16.309999999999999 15123 2012-01-20T08:00:00.000 RAW -16.37 -16.37 -17.8 0 0 2 93.5 6.3280000000000003 16.27 15.9 16.29 15123 2012-01-20T09:00:00.000 RAW -15.88 -16.78 -17.8 0 0 2 87.7 6.26 16.78 15.36 15.91 15123 2012-01-20T10:00:00.000 RAW -15.88 -16.18 -17.8 0 0 2 93.4 6.0830000000000002 14.13 12.72 18.72 15123 2012-01-20T11:00:00.000 RAW -15.55 -15.64 -17.8 0 0 3 94.1 7.43 17.22 14.49 18.47 15123 2012-01-20T12:00:00.000 RAW -14.71 -14.76 -17.8 0 0 3 94.2 4.1479999999999997 12.74 12.16 21.85 15123 2012-01-20T13:00:00.000 RAW -12.58 -12.58 -17.8 0 0 5 95.9 5.0609999999999999 15.32 21.65 21.02 15123 2012-01-20T14:00:00.000 RAW -11.31 -11.89 -17.8 0 0 5 93.8 0.63400000000000001 13.62 313.60000000000002 32.270000000000003 15123 2012-01-20T15:00:00.000 RAW -10.45 -10.61 -17.8 0 0 7 97.6 0.61199999999999999 6.6180000000000003 347.7 16.37 15123 2012-01-20T16:00:00.000 RAW -9.48 -9.48 -17.8 0 0 8 98.5 0 0.126 318.3 0.374 15123 2012-01-20T17:00:00.000 RAW -8.3699999999999992 -10.69 -17.8 0 0 8 98.2 0.109 2.8359999999999999 18.98 12.42 15123 2012-01-20T18:00:00.000 ST -8.3699999999999992 -10.52 -17.8 0 0 8 96.1 0.309 4.601 334.3 4.0229999999999997 15123 2012-01-20T19:00:00.000 RAW -7.63 -7.69 -10.52 0 0 3 98.6 2E-3 0.252 340.8 3.4319999999999999 15123 2012-01-20T20:00:00.000 RAW -6.9960000000000004 -8.85 -10.52 0 0 4 100.1 1.6E-2 1.1339999999999999 335 1.119 15123 2012-01-20T21:00:00.000 RAW -6.9960000000000004 -8.7799999999999994 -10.52 0 0 8 103.3 5.1999999999999998E-2 3.0880000000000001 352.8 5.8170000000000002 15123 2012-01-20T22:00:00.000 RAW -6.9960000000000004 -7.52 -10.52 0 0 14 109 3.0000000000000001E-3 0.252 345.4 6.3159999999999998 15123 2012-01-20T23:00:00.000 RAW -6.1849999999999996 -6.3019999999999996 -10.52 0 0 17 111.4 0 0.126 350 3.8220000000000001 15123 2012-01-21T00:00:00.000 RAW -4.6769999999999996 -4.6769999999999996 -10.52 0 0 20 114.4 0 0 0 0 15123 2012-01-21T01:00:00.000 RAW -3.48 -3.48 -10.52 0 0 20 114.1 0 6.3E-2 138.9 0 15123 2012-01-21T02:00:00.000 RAW -2.8620000000000001 -2.89 -10.52 0 0 20 111.9 0 0 0 0 15123 2012-01-21T03:00:00.000 RAW -1.3720000000000001 -1.3720000000000001 -10.52 0 0 21 114.5 5.2999999999999999E-2 1.764 182 0.64100000000000001 15123 2012-01-21T04:00:00.000 RAW -0.501 -0.54 -10.52 0 0 22 114.3 0.53400000000000003 5.8570000000000002 174.8 4.5179999999999998 15123 2012-01-21T05:00:00.000 RAW -0.30399999999999999 -0.33200000000000002 -10.52 0 0 22 113.3 3.1E-2 1.448 159.4 4.931 15123 2012-01-21T06:00:00.000 ST -0.219 -0.219 -10.52 0 0 22 113.5 0.26400000000000001 4.1550000000000002 157.19999999999999 8.5399999999999991 15123 2012-01-21T07:00:00.000 RAW -9.6000000000000002E-2 -0.47399999999999998 -0.49299999999999999 0 0 0 111.6 7.9 31.6 145.80000000000001 24.3 15123 2012-01-21T08:00:00.000 RAW -9.6000000000000002E-2 -1.5920000000000001 -1.611 0 0 0 111.9 15.27 42.37 149.80000000000001 26.62 15123 2012-01-21T09:00:00.000 RAW -9.6000000000000002E-2 -1.4590000000000001 -1.62 0 0 0 111.9 13.79 40.99 147.30000000000001 29.35 15123 2012-01-21T10:00:00.000 RAW -9.6000000000000002E-2 -1.1839999999999999 -1.62 0 0 0 111.5 14.88 35.700000000000003 154.30000000000001 20.75 15123 2012-01-21T11:00:00.000 RAW -9.6000000000000002E-2 -1.0329999999999999 -1.62 0 0 0 109.9 13.52 48.1 157.19999999999999 25.05 15123 2012-01-21T12:00:00.000 RAW -9.6000000000000002E-2 -1.175 -1.62 0 0 0 110.9 14.55 53.77 157.1 30.72 15123 2012-01-21T13:00:00.000 RAW -9.6000000000000002E-2 -1.1759999999999999 -1.62 0 0 0 111 13.82 38.97 158 25.02 15123 2012-01-21T14:00:00.000 RAW -9.6000000000000002E-2 -1.2989999999999999 -1.62 0 0 0 110.3 14.02 41.24 163.19999999999999 25.88 15123 2012-01-21T15:00:00.000 RAW -9.6000000000000002E-2 -1.554 -1.62 0 0 0 108 14.96 46.9 162.1 24.45 15123 2012-01-21T16:00:00.000 RAW -9.6000000000000002E-2 -1.7909999999999999 -1.8009999999999999 0 0 1 111.5 13.3 46.46 157.5 21.05 15123 2012-01-21T17:00:00.000 RAW -9.6000000000000002E-2 -2.2269999999999999 -2.2370000000000001 0 0 1 110.3 13.19 37.770000000000003 157.30000000000001 21.84 15123 2012-01-21T18:00:00.000 ST -9.6000000000000002E-2 -2.331 -2.3410000000000002 0 0 11.65 33.81 158.80000000000001 18.489999999999998 15123 2012-01-21T19:00:00.000 RAW -2.331 -2.512 -2.512 0 0 6 112.2 12.51 32.049999999999997 156.6 22.61 15123 2012-01-21T20:00:00.000 RAW -2.331 -2.74 -2.74 0 0 7 112.5 14.07 41.11 160.9 20.72 15123 2012-01-21T21:00:00.000 RAW -2.331 -3.073 -3.0819999999999999 0 0 9 114.1 15.76 40.729999999999997 164.4 22.27 15123 2012-01-21T22:00:00.000 RAW -2.331 -3.2919999999999998 -3.3109999999999999 0 0 9 114.1 15.01 40.36 161.4 20.18 15123 2012-01-21T23:00:00.000 RAW -2.331 -3.3959999999999999 -3.3959999999999999 0 0 9 111 11.66 31.55 160.80000000000001 21.39 15123 2012-01-22T00:00:00.000 RAW -2.331 -3.5779999999999998 -3.5779999999999998 0 0 10 114.3 9.31 29.97 152.6 21.07 15123 2012-01-22T01:00:00.000 RAW -2.331 -3.7970000000000002 -3.7970000000000002 0 0 10 114.6 7.71 21.66 144.1 22.26 15123 2012-01-22T02:00:00.000 RAW -2.331 -3.8540000000000001 -3.8540000000000001 0 0 11 114.9 7.76 19.899999999999999 148.4 19.48 15123 2012-01-22T03:00:00.000 RAW -2.331 -3.96 -3.96 0 0 8.1 22.54 149.4 17.420000000000002 15123 2012-01-22T04:00:00.000 RAW -2.331 -4.2370000000000001 -4.2370000000000001 0 0 11 114.3 6.4820000000000002 23.43 146.5 13.01 15123 2012-01-22T05:00:00.000 RAW -2.331 -4.3520000000000003 -4.3520000000000003 0 0 11 113.9 2.7570000000000001 12.28 144.80000000000001 11.45 15123 2012-01-22T06:00:00.000 ST -2.331 -4.6399999999999997 -4.6399999999999997 0 0 11 114 2.3380000000000001 9.57 141.69999999999999 9.61 15123 2012-01-22T07:00:00.000 RAW -4.63 -4.63 -4.88 0 0 0 113.8 7.6999999999999999E-2 2.3929999999999998 144.80000000000001 5.4880000000000004 15123 2012-01-22T08:00:00.000 RAW -4.601 -4.7460000000000004 -4.88 0 0 0 113.3 0.01 0.441 147 4.6769999999999996 15123 2012-01-22T09:00:00.000 RAW -4.2939999999999996 -4.3419999999999996 -4.88 0 0 0 113.1 5.0000000000000001E-3 0.63 147.9 2.6059999999999999 15123 2012-01-22T10:00:00.000 RAW -3.4529999999999998 -3.4529999999999998 -4.88 0 0 0 113.2 0.02 1.3859999999999999 146 1.3080000000000001 15123 2012-01-22T11:00:00.000 RAW -2.891 -2.8919999999999999 -4.88 0 0 0 112.9 5.0000000000000001E-3 0.504 171.6 2.4910000000000001 15123 2012-01-22T12:00:00.000 RAW -2.512 -2.7210000000000001 -4.88 0 0 0 112.6 0.73899999999999999 11.46 126.8 13.27 15123 2012-01-22T13:00:00.000 RAW -2.512 -3.1120000000000001 -4.88 0 0 0 112.6 1.1080000000000001 6.9880000000000004 165.7 13.99 15123 2012-01-22T14:00:00.000 RAW -2.512 -3.2349999999999999 -4.88 0 0 3 115.3 0 6.3E-2 212.2 2E-3 15123 2012-01-22T15:00:00.000 RAW -2.512 -3.13 -4.88 0 0 7 119.7 0 0 0 0 15123 2012-01-22T16:00:00.000 RAW -2.512 -3.101 -4.88 0 0 9 120.5 0 0 0 0 15123 2012-01-22T17:00:00.000 RAW -2.512 -2.9580000000000002 -4.88 0 0 15 126.7 9.8000000000000004E-2 2.0150000000000001 194 16.329999999999998 15123 2012-01-22T18:00:00.000 ST -2.512 -2.7389999999999999 -4.88 0 0 16 126.4 0.39900000000000002 4.8479999999999999 172.6 16.309999999999999 15123 2012-01-22T19:00:00.000 RAW -2.4830000000000001 -2.4830000000000001 -2.74 0 0 1.3939999999999999 12.15 178.3 22.95 15123 2012-01-22T20:00:00.000 RAW -2.008 -2.2639999999999998 -2.74 0 0 4 129.9 3.86 27.64 152.6 32.270000000000003 15123 2012-01-22T21:00:00.000 RAW -2.008 -2.3210000000000002 -2.74 0 0 5 130.30000000000001 8.65 31.16 151.1 35.369999999999997 15123 2012-01-22T22:00:00.000 RAW -2.008 -2.5499999999999998 -2.74 0 0 5 129.5 11.51 44.01 160.30000000000001 38.32 15123 2012-01-22T23:00:00.000 RAW -2.008 -2.5110000000000001 -2.74 0 0 5 130.19999999999999 12.82 44.58 167.7 38.659999999999997 15123 2012-01-23T00:00:00.000 RAW -2.008 -2.72 -2.74 0 0 5 129.6 14.39 42.88 166 35.409999999999997 15123 2012-01-23T01:00:00.000 RAW -2.008 -2.863 -2.8820000000000001 0 0 9.08 37.590000000000003 162.6 29.91 15123 2012-01-23T02:00:00.000 RAW -2.008 -2.8540000000000001 -2.8820000000000001 0 0 8 131.9 10.050000000000001 44.96 159.69999999999999 25.97 15123 2012-01-23T03:00:00.000 RAW -2.008 -2.9580000000000002 -2.9769999999999999 0 0 9 132.9 15.65 37.97 163 33.04 15123 2012-01-23T04:00:00.000 RAW -2.008 -2.9769999999999999 -3.044 0 0 9 131.6 10.77 33.880000000000003 168.4 24.82 15123 2012-01-23T05:00:00.000 RAW -2.008 -3.0059999999999998 -3.0529999999999999 0 0 9 129.6 5.7220000000000004 20.84 164.1 20.94 15123 2012-01-23T06:00:00.000 ST -2.008 -3.0150000000000001 -3.0630000000000002 0 0 9 128.4 6.8639999999999999 23.17 160.1 21.79 15123 2012-01-23T07:00:00.000 RAW -3.0150000000000001 -3.101 -3.149 0 0 3 131.1 7.44 19.14 158.6 19.36 15123 2012-01-23T08:00:00.000 RAW -3.0150000000000001 -3.044 -3.149 0 0 3 131.1 6.319 17.32 156.80000000000001 19.07 15123 2012-01-23T09:00:00.000 RAW -2.8149999999999999 -2.8149999999999999 -3.149 0 0 3 130.30000000000001 5.9930000000000003 18.2 155.19999999999999 21.28 15123 2012-01-23T10:00:00.000 RAW -2.4540000000000002 -2.4729999999999999 -3.149 0 0 3 129.80000000000001 6.7190000000000003 23.49 158.6 22.88 15123 2012-01-23T11:00:00.000 RAW -2.0939999999999999 -2.1219999999999999 -3.149 0 0 3 130.5 11.23 30.53 157.9 24.27 15123 2012-01-23T12:00:00.000 RAW -1.175 -1.27 -3.149 0 0 3 129.4 8.11 24.99 164.9 23.06 15123 2012-01-23T13:00:00.000 RAW -1.1000000000000001 -1.2330000000000001 -3.149 0 0 3 128.30000000000001 11 29.84 169.4 22.1 15123 2012-01-23T14:00:00.000 RAW -1.016 -1.016 -3.149 0 0 3 128.19999999999999 10.07 27.13 167 21.17 15123 2012-01-23T15:00:00.000 RAW -0.86499999999999999 -1.925 -3.149 0 0 3 123.9 7.33 18.88 159.5 23.65 15123 2012-01-23T16:00:00.000 RAW -0.86499999999999999 -2.1619999999999999 -3.149 0 0 3 125.1 9.8000000000000007 27.26 155.19999999999999 23.13 15123 2012-01-23T17:00:00.000 RAW -0.86499999999999999 -2.5310000000000001 -3.149 0 0 3 125.5 8.9 28.21 157.69999999999999 24.51 15123 2012-01-23T18:00:00.000 ST -0.86499999999999999 -2.6160000000000001 -3.149 0 0 3 126.6 7.75 20.02 159.9 21.15 15123 2012-01-23T19:00:00.000 RAW -2.5680000000000001 -2.6440000000000001 -2.6819999999999999 0 0 0 126.8 7.94 21.09 156.6 25.03 15123 2012-01-23T20:00:00.000 RAW -2.4540000000000002 -2.464 -2.7010000000000001 0 0 1 127.3 4.9820000000000002 21.41 150.4 22.64 15123 2012-01-23T21:00:00.000 RAW -2.3969999999999998 -2.4449999999999998 -2.7010000000000001 0 0 1 126.6 7.94 27.51 153.9 21.61 15123 2012-01-23T22:00:00.000 RAW -2.3879999999999999 -2.4350000000000001 -2.7010000000000001 0 0 1 125.6 8.44 23.67 150.80000000000001 21.98 15123 2012-01-23T23:00:00.000 RAW -2.3690000000000002 -2.5489999999999999 -2.7010000000000001 0 0 1 125.2 7.53 23.61 150 23.99 15123 2012-01-24T00:00:00.000 RAW -2.3690000000000002 -2.73 -2.7490000000000001 0 0 1 125.9 7.08 21.78 151.80000000000001 19.5 15123 2012-01-24T01:00:00.000 RAW -2.3690000000000002 -3.0249999999999999 -3.0249999999999999 0 0 1 125.7 7.41 21.28 165.6 16.53 15123 2012-01-24T02:00:00.000 RAW -2.3690000000000002 -2.968 -3.0819999999999999 0 0 1 124.6 7.14 18.260000000000002 162.30000000000001 17.78 15123 2012-01-24T03:00:00.000 RAW -2.3690000000000002 -3.0819999999999999 -3.12 0 0 1 125.3 7.62 19.84 176.6 18.350000000000001 15123 2012-01-24T04:00:00.000 RAW -2.3690000000000002 -3.3109999999999999 -3.33 0 0 1 123.9 6.5970000000000004 15.68 161.9 17.93 15123 2012-01-24T05:00:00.000 RAW -2.3690000000000002 -3.0150000000000001 -3.3490000000000002 0 0 1 124.5 8.8000000000000007 29.53 173.4 26.26 15123 2012-01-24T06:00:00.000 ST -2.3690000000000002 -3.2719999999999998 -3.3490000000000002 0 0 1 122.5 5.6920000000000002 21.6 171.5 20.329999999999998 15123 2012-01-24T07:00:00.000 RAW -3.1859999999999999 -3.3290000000000002 -3.33 0 0 3 125.1 2.41 11.65 147.30000000000001 21.19 15123 2012-01-24T08:00:00.000 RAW -3.1859999999999999 -3.2909999999999999 -3.339 0 0 3 125.8 3.4140000000000001 12.91 149.30000000000001 18.559999999999999 15123 2012-01-24T09:00:00.000 RAW -2.7679999999999998 -2.7679999999999998 -3.339 0 0 4 125.9 1.9159999999999999 13.35 152.80000000000001 16.690000000000001 15123 2012-01-24T10:00:00.000 RAW -1.923 -1.923 -3.339 0 0 4 125.5 1.4930000000000001 10.33 172 17.82 15123 2012-01-24T11:00:00.000 RAW -1.2410000000000001 -1.2410000000000001 -3.339 0 0 4 122.1 2.1520000000000001 9.76 168.5 16.21 15123 2012-01-24T12:00:00.000 RAW -0.437 -0.437 -3.339 0 0 4 124.9 1.319 8.6300000000000008 174 12.1 15123 2012-01-24T13:00:00.000 RAW -0.314 -1.129 -3.339 0 0 6 127.4 1.968 9.32 188.1 14.55 15123 2012-01-24T14:00:00.000 RAW -0.28599999999999998 -0.504 -3.339 0 0 7 128.1 2.1999999999999999E-2 1.0069999999999999 185 4.7629999999999999 15123 2012-01-24T15:00:00.000 RAW -0.28599999999999998 -0.89100000000000001 -3.339 0 0 11 132.80000000000001 0.11 2.6440000000000001 220.3 5.6580000000000004 15123 2012-01-24T16:00:00.000 RAW -0.28599999999999998 -0.67400000000000004 -3.339 0 0 17 137.30000000000001 8.6999999999999994E-2 2.4550000000000001 232.5 6.157 15123 2012-01-24T17:00:00.000 RAW -0.28599999999999998 -0.95699999999999996 -3.339 0 0 20 140.30000000000001 0.17399999999999999 3.84 205.4 27.15 15123 2012-01-24T18:00:00.000 ST -0.28599999999999998 -0.437 -3.339 0 0 23 142 0.61399999999999999 5.226 179.5 47.47 15123 2012-01-24T19:00:00.000 RAW -0.248 -0.248 -0.437 0 0 4 145.30000000000001 0.56599999999999995 7.81 172.8 47.21 15123 2012-01-24T20:00:00.000 RAW -0.04 -0.182 -0.437 0 0 4 144.9 2.3780000000000001 17.940000000000001 154.9 58.04 15123 2012-01-24T21:00:00.000 RAW 5.5E-2 8.0000000000000002E-3 -0.437 0 0 4 144.1 4.7859999999999996 25.25 148.80000000000001 49.02 15123 2012-01-24T22:00:00.000 RAW 0.376 0.31 -0.437 0 0 4 142.9 10.029999999999999 44.76 151 45.33 15123 2012-01-24T23:00:00.000 RAW 0.745 0.66 -0.437 0 0 4 141.5 13.29 36.200000000000003 143.5 37.630000000000003 15123 2012-01-25T00:00:00.000 RAW 0.83 0.54700000000000004 -0.437 0 0 4 140.69999999999999 17.34 65.599999999999994 168.9 35.630000000000003 15123 2012-01-25T01:00:00.000 RAW 0.84899999999999998 0.42399999999999999 -0.437 0 0 4 140.1 18.36 61.76 202.1 42.22 15123 2012-01-25T02:00:00.000 RAW 0.84899999999999998 8.0000000000000002E-3 -0.437 0 0 4 139 10.14 47.28 210.2 49.89 15123 2012-01-25T03:00:00.000 RAW 0.84899999999999998 0.159 -0.437 0 0 4 138.5 14.35 51.25 209.9 42.78 15123 2012-01-25T04:00:00.000 RAW 0.84899999999999998 -0.25700000000000001 -0.437 0 0 4 137.5 9.17 45.96 208.2 49.57 15123 2012-01-25T05:00:00.000 RAW 0.84899999999999998 -0.70199999999999996 -0.72099999999999997 0 0 4 136.6 12.73 51.31 204.6 45.61 15123 2012-01-25T06:00:00.000 ST 0.84899999999999998 -1.81 -1.81 0 0 4 136.4 12.53 58.8 208.8 44.85 15123 2012-01-25T07:00:00.000 RAW -1.81 -2.3130000000000002 -2.3130000000000002 0 0 0.1 136.6 11.75 52.19 205.8 39.619999999999997 15123 2012-01-25T08:00:00.000 RAW -1.81 -2.4449999999999998 -2.74 0 0 0 136 15.7 31.35 182 24.63 15123 2012-01-25T09:00:00.000 RAW -1.81 -2.331 -2.74 0 0 0 135.4 12 33.68 171.6 23.52 15123 2012-01-25T10:00:00.000 RAW -1.81 -2.056 -2.74 0 0 0 134.9 13.12 30.22 170.7 19.940000000000001 15123 2012-01-25T11:00:00.000 RAW -1.81 -1.895 -2.74 0 0 0.1 135.80000000000001 11.49 31.92 157.19999999999999 25 15123 2012-01-25T12:00:00.000 RAW -1.7430000000000001 -1.81 -2.74 0 0 0 134.69999999999999 12.58 28.46 154.19999999999999 27.1 15123 2012-01-25T13:00:00.000 RAW -1.194 -1.2130000000000001 -2.74 0 0 1 136.1 12.28 29.21 165.6 22.15 15123 2012-01-25T14:00:00.000 RAW -1.1279999999999999 -1.536 -2.74 0 0 2 136.9 14.06 41.17 172 27.02 15123 2012-01-25T15:00:00.000 RAW -1.1279999999999999 -1.7250000000000001 -2.74 0 0 3 136.9 18.12 45.27 185 26.72 15123 2012-01-25T16:00:00.000 RAW -1.1279999999999999 -2.2370000000000001 -2.74 0 0 3 136.4 18.18 41.36 182.4 27.47 15123 2012-01-25T17:00:00.000 RAW -1.1279999999999999 -2.4359999999999999 -2.74 0 0 3 136.1 16.04 38.53 184.8 25.79 15123 2012-01-25T18:00:00.000 ST -1.1279999999999999 -2.8159999999999998 -2.8250000000000002 0 0 3 135.5 15.38 38.15 177 21.86 15123 2012-01-25T19:00:00.000 RAW -2.8159999999999998 -3.1869999999999998 -3.1970000000000001 0 0 1 136.30000000000001 15.52 30.47 166.4 21.84 15123 2012-01-25T20:00:00.000 RAW -2.8159999999999998 -3.073 -3.206 0 0 1 136.5 9.5399999999999991 20.52 152.6 22.99 15123 2012-01-25T21:00:00.000 RAW -2.8159999999999998 -2.9489999999999998 -3.206 0 0 2 137.6 5.7690000000000001 14.73 158.6 21.28 15123 2012-01-25T22:00:00.000 RAW -2.8159999999999998 -3.0339999999999998 -3.206 0 0 5 139.80000000000001 2.944 11.84 160.19999999999999 19.55 15123 2012-01-25T23:00:00.000 RAW -2.8159999999999998 -3.0350000000000001 -3.206 0 0 6 140.6 3.782 12.53 158.1 24.25 15123 2012-01-26T00:00:00.000 RAW -2.8159999999999998 -2.9390000000000001 -3.206 0 0 6 139.9 3.9860000000000002 15.43 162.4 21.07 15123 2012-01-26T01:00:00.000 RAW -2.8159999999999998 -2.863 -3.206 0 0 9 143.30000000000001 1.4670000000000001 10.64 174.4 14.92 15123 2012-01-26T02:00:00.000 RAW -2.5880000000000001 -2.6059999999999999 -3.206 0 0 9 140.1 0.38300000000000001 4.282 181.5 9.33 15123 2012-01-26T03:00:00.000 RAW -2.4449999999999998 -2.4449999999999998 -3.206 0 0 9 141.6 1.6870000000000001 10.77 162.19999999999999 16.7 15123 2012-01-26T04:00:00.000 RAW -2.0840000000000001 -2.5019999999999998 -3.206 0 0 13 146.69999999999999 9.67 23.17 165.5 16.89 15123 2012-01-26T05:00:00.000 RAW -1.8089999999999999 -1.875 -3.206 0 0 14 147.1 10.66 23.04 166.9 16.96 15123 2012-01-26T06:00:00.000 ST -1.8089999999999999 -1.9610000000000001 -3.206 0 0 14 147.19999999999999 13.6 32.11 169.2 18.489999999999998 15123 2012-01-26T07:00:00.000 RAW -1.9039999999999999 -2.17 -2.17 0 0 2 149.4 15.89 42.81 166.6 28.19 15123 2012-01-26T08:00:00.000 RAW -1.9039999999999999 -2.7679999999999998 -2.7679999999999998 0 0 4 150.69999999999999 15.36 39.35 169.2 29.14 15123 2012-01-26T09:00:00.000 RAW -1.9039999999999999 -2.883 -2.911 0 0 4 150.6 12.99 39.03 179.9 17.68 15123 2012-01-26T10:00:00.000 RAW -1.9039999999999999 -2.5779999999999998 -2.9590000000000001 0 0 6 152.4 9.36 23.67 165 17.18 15123 2012-01-26T11:00:00.000 RAW -1.9039999999999999 -2.9020000000000001 -3.0539999999999998 0 0 6 148.4 8.5399999999999991 23.17 169.2 21.89 15123 2012-01-26T12:00:00.000 RAW -1.9039999999999999 -2.8730000000000002 -3.0539999999999998 0 0 8 153.4 8.41 23.36 174.2 22.66 15123 2012-01-26T13:00:00.000 RAW -1.9039999999999999 -2.3980000000000001 -3.0539999999999998 0 0 8 151.19999999999999 5.2759999999999998 21.59 176.6 17.510000000000002 15123 2012-01-26T14:00:00.000 RAW -1.9039999999999999 -2.3319999999999999 -3.0539999999999998 0 0 5.391 33.75 194.2 36.590000000000003 15123 2012-01-26T15:00:00.000 RAW -1.9039999999999999 -2.57 -3.0539999999999998 0 0 8 151.6 6.2320000000000002 20.399999999999999 188.9 21.04 15123 2012-01-26T16:00:00.000 RAW -1.9039999999999999 -3.4359999999999999 -3.4359999999999999 0 0 8 150.1 6.55 24.11 189.1 20.3 15123 2012-01-26T17:00:00.000 RAW -1.9039999999999999 -4.0469999999999997 -4.0469999999999997 0 0 8 148.19999999999999 12.21 25.12 176.9 17.649999999999999 15123 2012-01-26T18:00:00.000 ST -1.9039999999999999 -4.2370000000000001 -4.2569999999999997 0 0 8 149.30000000000001 11.34 25.06 169 18.86 15123 2012-01-26T19:00:00.000 RAW -4.2370000000000001 -4.41 -4.41 0 0 2 151 12.77 34.01 167.9 22.38 15123 2012-01-26T20:00:00.000 RAW -4.2370000000000001 -4.5919999999999996 -4.6020000000000003 0 0 2 149.19999999999999 10.88 27.08 165.8 21.22 15123 2012-01-26T21:00:00.000 RAW -4.2370000000000001 -4.9089999999999998 -4.9279999999999999 0 0 2 147.5 11.92 30.92 169 18.04 15123 2012-01-26T22:00:00.000 RAW -4.2370000000000001 -4.9950000000000001 -5.2080000000000002 0 0 2 147.9 9.1300000000000008 22.8 153 21.34 15123 2012-01-26T23:00:00.000 RAW -4.2370000000000001 -5.3040000000000003 -5.3140000000000001 0 0 2 147.9 8.43 20.34 156.30000000000001 21.97 15123 2012-01-27T00:00:00.000 RAW -4.2370000000000001 -5.7009999999999996 -5.7009999999999996 0 0 2 148 7.86 23.05 164.8 20.46 15123 2012-01-27T01:00:00.000 RAW -4.2370000000000001 -5.5069999999999997 -5.8849999999999998 0 0 2 147.69999999999999 6.8869999999999996 14.68 166.3 14.28 15123 2012-01-27T02:00:00.000 RAW -4.2370000000000001 -5.3719999999999999 -5.8849999999999998 0 0 2 147.6 8.15 21.98 162.30000000000001 16.510000000000002 15123 2012-01-27T03:00:00.000 RAW -4.2370000000000001 -5.43 -5.8849999999999998 0 0 2 147.80000000000001 8.01 18.14 167.2 13.53 15123 2012-01-27T04:00:00.000 RAW -4.2370000000000001 -4.9850000000000003 -5.8849999999999998 0 0 2 147.19999999999999 8.7100000000000009 17.13 165.5 13.3 15123 2012-01-27T05:00:00.000 RAW -4.2370000000000001 -4.8600000000000003 -5.8849999999999998 0 0 2 146.80000000000001 8.58 25.45 167.7 18.09 15123 2012-01-27T06:00:00.000 ST -4.2370000000000001 -4.8609999999999998 -5.8849999999999998 0 0 2 146.30000000000001 8.9499999999999993 21.79 165 17.37 15123 2012-01-27T07:00:00.000 RAW -4.8609999999999998 -4.9089999999999998 -5.1980000000000004 0 0 0 146 8.9700000000000006 19.649999999999999 159.30000000000001 20.38 15123 2012-01-27T08:00:00.000 RAW -4.7930000000000001 -4.87 -5.1980000000000004 0 0 0 143.30000000000001 9.7799999999999994 21.73 153 24.35 15123 2012-01-27T09:00:00.000 RAW -4.63 -4.6399999999999997 -5.1980000000000004 0 0 12.35 31.74 151.69999999999999 25.08 15123 2012-01-27T10:00:00.000 RAW -4.4189999999999996 -4.4859999999999998 -5.1980000000000004 0 0 2 147.69999999999999 11.99 26.14 149 25.19 15123 2012-01-27T11:00:00.000 RAW -4.2850000000000001 -4.2850000000000001 -5.1980000000000004 0 0 2 147.30000000000001 12.88 26.07 148.30000000000001 24.97 15123 2012-01-27T12:00:00.000 RAW -4.0170000000000003 -4.0170000000000003 -5.1980000000000004 0 0 2 146.6 11.49 25.82 146.6 27.04 15123 2012-01-27T13:00:00.000 RAW -3.6640000000000001 -3.75 -5.1980000000000004 0 0 2 147.69999999999999 11.35 26.76 155.5 24.38 15123 2012-01-27T14:00:00.000 RAW -3.5110000000000001 -3.5880000000000001 -5.1980000000000004 0 0 2 146.9 10.96 23.24 150.80000000000001 25.94 15123 2012-01-27T15:00:00.000 RAW -3.5110000000000001 -3.8460000000000001 -5.1980000000000004 0 0 3 148.1 12.49 29.97 152.1 25.94 15123 2012-01-27T16:00:00.000 RAW -3.5110000000000001 -4.1230000000000002 -5.1980000000000004 0 0 4 148.69999999999999 12.22 26.95 156.1 30.06 15123 2012-01-27T17:00:00.000 RAW -3.5110000000000001 -4.3529999999999998 -5.1980000000000004 0 0 4 148.6 13.41 30.54 152.5 25.86 15123 2012-01-27T18:00:00.000 ST -3.5110000000000001 -4.3239999999999998 -5.1980000000000004 0 0 4 146.6 12.71 38.04 152.4 24.77 15123 2012-01-27T19:00:00.000 RAW -4.3239999999999998 -4.4189999999999996 -4.4189999999999996 0 0 1 147.69999999999999 10.74 24.5 148.80000000000001 25.59 15123 2012-01-27T20:00:00.000 RAW -4.3239999999999998 -4.4000000000000004 -4.4580000000000002 0 0 2 148.30000000000001 9.8000000000000007 21.92 149.19999999999999 23.33 15123 2012-01-27T21:00:00.000 RAW -4.3239999999999998 -4.4000000000000004 -4.4580000000000002 0 0 2 145.4 10.42 19.59 153.4 20.399999999999999 15123 2012-01-27T22:00:00.000 RAW -4.3239999999999998 -4.3810000000000002 -4.4580000000000002 0 0 2 148.1 12.53 28.4 160.6 19.13 15123 2012-01-27T23:00:00.000 RAW -4.3239999999999998 -4.4189999999999996 -4.4580000000000002 0 0 2 148.19999999999999 14.73 28.21 170.2 18.510000000000002 15123 2012-01-28T00:00:00.000 RAW -4.3230000000000004 -4.3419999999999996 -4.4580000000000002 0 0 3 148.6 10.199999999999999 22.17 157.69999999999999 17.39 15123 2012-01-28T01:00:00.000 RAW -4.3230000000000004 -4.41 -4.4580000000000002 0 0 3 148.30000000000001 10.84 19.329999999999998 157.4 15.32 15123 2012-01-28T02:00:00.000 RAW -4.3230000000000004 -4.4480000000000004 -4.4859999999999998 0 0 3 148.19999999999999 10.45 20.41 149.69999999999999 14.57 15123 2012-01-28T03:00:00.000 RAW -4.3230000000000004 -4.5819999999999999 -4.5919999999999996 0 0 3 147.19999999999999 11.58 20.34 152.4 19.309999999999999 15123 2012-01-28T04:00:00.000 RAW -4.3230000000000004 -4.5730000000000004 -4.6109999999999998 0 0 3 146.9 10.68 18.96 153.69999999999999 15.21 15123 2012-01-28T05:00:00.000 RAW -4.3230000000000004 -4.5439999999999996 -4.6109999999999998 0 0 3 146.69999999999999 9.09 20.53 150.9 14.16 15123 2012-01-28T06:00:00.000 ST -4.3230000000000004 -4.4859999999999998 -4.6109999999999998 0 0 3 146.6 8.16 17.510000000000002 157.5 16.420000000000002 15123 2012-01-28T07:00:00.000 RAW -4.4859999999999998 -4.6109999999999998 -4.6779999999999999 0 0 0 146.4 9.4 22.99 150.30000000000001 21.73 15123 2012-01-28T08:00:00.000 RAW -4.4859999999999998 -4.7069999999999999 -4.7069999999999999 0 0 0 146.19999999999999 11.47 27.9 145.19999999999999 25.05 15123 2012-01-28T09:00:00.000 RAW -4.4859999999999998 -4.5730000000000004 -4.7939999999999996 0 0 0 146.5 10.16 22.92 143.6 24.17 15123 2012-01-28T10:00:00.000 RAW -4.1130000000000004 -4.1130000000000004 -4.7939999999999996 0 0 0.1 146.6 7.28 17.89 136.4 20.27 15123 2012-01-28T11:00:00.000 RAW -3.5870000000000002 -3.597 -4.7939999999999996 0 0 0.1 146.5 7.59 17.63 134.1 18.28 15123 2012-01-28T12:00:00.000 RAW -3.4060000000000001 -3.7690000000000001 -4.7939999999999996 0 0 1 146.6 13.17 32.619999999999997 152.6 20.89 15123 2012-01-28T13:00:00.000 RAW -3.044 -3.0830000000000002 -4.7939999999999996 0 0 1 146.30000000000001 15.64 35.51 162.5 21.36 15123 2012-01-28T14:00:00.000 RAW -3.044 -3.0920000000000001 -4.7939999999999996 0 0 1 146.19999999999999 17.57 32.86 169.6 23.7 15123 2012-01-28T15:00:00.000 RAW -2.9209999999999998 -3.016 -4.7939999999999996 0 0 1 146.19999999999999 19.37 39.79 171.4 24.08 15123 2012-01-28T16:00:00.000 RAW -2.198 -2.198 -4.7939999999999996 0 0 1 146.19999999999999 17.559999999999999 33.049999999999997 179.7 22.74 15123 2012-01-28T17:00:00.000 RAW -1.345 -1.4019999999999999 -4.7939999999999996 0 0 1 145.5 13.77 46.4 200.4 26.58 15123 2012-01-28T18:00:00.000 ST -0.51200000000000001 -0.64400000000000002 -4.7939999999999996 0 0 1 145 13.91 36.83 202.5 29.76 15123 2012-01-28T19:00:00.000 RAW 0.33 0.33 -0.64400000000000002 0 0 0 144.19999999999999 14.13 44.64 196.6 28.55 15123 2012-01-28T20:00:00.000 RAW 0.878 0.79300000000000004 -0.64400000000000002 0 0 0 144.4 14.78 47.66 207 31.3 15123 2012-01-28T21:00:00.000 RAW 1.171 0.33900000000000002 -0.64400000000000002 0 0 0 144.30000000000001 13.4 40.04 205.2 30.19 15123 2012-01-28T22:00:00.000 RAW 1.171 -0.16300000000000001 -0.64400000000000002 0 0 0 144.1 14.26 30.85 181.4 23.39 15123 2012-01-28T23:00:00.000 RAW 1.171 0.36699999999999999 -0.64400000000000002 0 0 0 144.1 14.33 27.95 176 20.28 15123 2012-01-29T00:00:00.000 RAW 1.171 0.81100000000000005 -0.64400000000000002 0 0 0 143.80000000000001 15.95 31.79 169.8 20.83 15123 2012-01-29T01:00:00.000 RAW 1.171 0.86799999999999999 -0.64400000000000002 0 0 0 143.19999999999999 13.4 29.65 182.1 21.73 15123 2012-01-29T02:00:00.000 RAW 1.5109999999999999 1.2090000000000001 -0.64400000000000002 0 0 0 142.9 9.42 25.94 194 23.97 15123 2012-01-29T03:00:00.000 RAW 1.5109999999999999 0.63100000000000001 -0.64400000000000002 0 0 0 142.4 10.85 31.35 185.8 23.39 15123 2012-01-29T04:00:00.000 RAW 1.5109999999999999 -0.16300000000000001 -0.64400000000000002 0 0 0 141.69999999999999 14.23 37.840000000000003 161.30000000000001 23 15123 2012-01-29T05:00:00.000 RAW 1.5109999999999999 0.36699999999999999 -0.64400000000000002 0 0 0 141.5 14.82 30.22 147.30000000000001 23.87 15123 2012-01-29T06:00:00.000 ST 1.5109999999999999 0.67900000000000005 -0.64400000000000002 0 0 0 140.9 15.23 30.72 143.6 26.7 15123 2012-01-29T07:00:00.000 RAW 1.161 1.161 0.66900000000000004 0 0 0 140.6 13.91 36.96 144.6 29.18 15123 2012-01-29T08:00:00.000 RAW 1.4550000000000001 1.417 0.66900000000000004 0 0 0 140.1 16.23 35.82 169.5 19.14 15123 2012-01-29T09:00:00.000 RAW 2.1739999999999999 2.1739999999999999 0.66900000000000004 0 0 0 140 11.38 24.93 182.2 20.55 15123 2012-01-29T10:00:00.000 RAW 2.714 2.6949999999999998 0.66900000000000004 0 0 0 139.80000000000001 12.82 31.98 163.30000000000001 22.2 15123 2012-01-29T11:00:00.000 RAW 2.8940000000000001 2.694 0.66900000000000004 0 0 0 139 13.09 27.88 156.80000000000001 24.28 15123 2012-01-29T12:00:00.000 RAW 2.8940000000000001 2.5049999999999999 0.66900000000000004 0 0 0 138.1 11.73 28.7 157.1 22.94 15123 2012-01-29T13:00:00.000 RAW 2.8940000000000001 1.917 0.66900000000000004 0 0 0 136.9 9.84 24.36 154.6 23.75 15123 2012-01-29T14:00:00.000 RAW 2.8940000000000001 1.2549999999999999 0.66900000000000004 0 0 0 136.30000000000001 11.86 31.91 145.9 26.6 15123 2012-01-29T15:00:00.000 RAW 2.8940000000000001 1.208 0.66900000000000004 0 0 0 135.1 11.18 25.74 140.6 29.96 15123 2012-01-29T16:00:00.000 RAW 2.8940000000000001 0.84799999999999998 0.66900000000000004 0 0 0 135.9 9.6300000000000008 25.68 138.19999999999999 30.13 15123 2012-01-29T17:00:00.000 RAW 2.8940000000000001 0.58399999999999996 0.55500000000000005 0 0 0 135.4 11.68 25.55 139 24.32 15123 2012-01-29T18:00:00.000 ST 2.8940000000000001 0.53700000000000003 0.52700000000000002 0 0 0 134.80000000000001 12.15 28.01 132.69999999999999 21.89 15123 2012-01-29T19:00:00.000 RAW 0.67900000000000005 0.67900000000000005 0.51800000000000002 0 0 0 134.4 11.59 22.54 137.30000000000001 19.96 15123 2012-01-29T20:00:00.000 RAW 0.82 0.79200000000000004 0.51800000000000002 0 0 0 134.1 11.24 22.85 148.5 23.3 15123 2012-01-29T21:00:00.000 RAW 1.1419999999999999 1.0860000000000001 0.51800000000000002 0 0 0 133.5 11.88 33.36 144 21.31 15123 2012-01-29T22:00:00.000 RAW 1.5209999999999999 1.52 0.51800000000000002 0 0 0 132.6 10.7 23.73 137.5 16.399999999999999 15123 2012-01-29T23:00:00.000 RAW 1.587 1.492 0.51800000000000002 0 0 0 132.69999999999999 8.4499999999999993 20.71 140.9 17.77 15123 2012-01-30T00:00:00.000 RAW 1.587 1.359 0.51800000000000002 0 0 0 129.69999999999999 8.61 18 144.80000000000001 16.82 15123 2012-01-30T01:00:00.000 RAW 1.587 1.2649999999999999 0.51800000000000002 0 0 0 129.5 8.6 20.079999999999998 142.1 22.15 15123 2012-01-30T02:00:00.000 RAW 1.587 0.98099999999999998 0.51800000000000002 0 0 0 130.19999999999999 8.35 22.98 138.30000000000001 24.76 15123 2012-01-30T03:00:00.000 RAW 1.587 1.048 0.51800000000000002 0 0 0 130.5 11.28 30.09 140.6 24.42 15123 2012-01-30T04:00:00.000 RAW 1.587 1.218 0.51800000000000002 0 0 0 130.19999999999999 13.77 29.71 147.30000000000001 22.19 15123 2012-01-30T05:00:00.000 RAW 1.587 1.1040000000000001 0.51800000000000002 0 0 0 129.69999999999999 13.07 30.53 146.6 19.579999999999998 15123 2012-01-30T06:00:00.000 ST 1.587 0.99099999999999999 0.51800000000000002 0 0 0 129.1 12.67 26.56 155.9 24.78 15123 2012-01-30T07:00:00.000 RAW 1.0089999999999999 0.64100000000000001 0.63100000000000001 0 0 0 129.1 13.84 37.89 159.1 26.47 15123 2012-01-30T08:00:00.000 RAW 1.0089999999999999 0.111 0.111 0 0 0 128.69999999999999 12.09 29.52 152 27.66 15123 2012-01-30T09:00:00.000 RAW 1.0089999999999999 -0.35199999999999998 -0.36199999999999999 0 0 0 128.4 14.53 39.659999999999997 155.5 29.78 15123 2012-01-30T10:00:00.000 RAW 1.0089999999999999 -0.48499999999999999 -0.48499999999999999 0 0 0 127.9 15.01 42.74 153.80000000000001 31.34 15123 2012-01-30T11:00:00.000 RAW 1.0089999999999999 -0.4 -0.504 0 0 0 127.5 12.48 30.59 149.6 29.7 15123 2012-01-30T12:00:00.000 RAW 1.0089999999999999 -0.21 -0.504 0 0 0 126.8 13.79 38.4 152.1 27.22 15123 2012-01-30T13:00:00.000 RAW 1.0089999999999999 -0.14499999999999999 -0.504 0 0 0 127.3 11.98 26.31 146.30000000000001 24.69 15123 2012-01-30T14:00:00.000 RAW 1.0089999999999999 0.28999999999999998 -0.504 0 0 0 127.1 10.11 23.79 148.6 27.92 15123 2012-01-30T15:00:00.000 RAW 1.0089999999999999 -0.249 -0.504 0 0 0 127.1 12.53 28.07 155.19999999999999 23.16 15123 2012-01-30T16:00:00.000 RAW 1.0089999999999999 -0.40899999999999997 -0.504 0 0 0 126.8 12.47 32.979999999999997 148.69999999999999 27.77 15123 2012-01-30T17:00:00.000 RAW 1.0089999999999999 -0.61699999999999999 -0.61699999999999999 0 0 0 126.5 10.8 29.71 145.80000000000001 26.94 15123 2012-01-30T18:00:00.000 ST 1.0089999999999999 -0.64500000000000002 -0.65500000000000003 0 0 0 126.3 12.39 27.07 145.6 24.54 15123 2012-01-30T19:00:00.000 RAW -0.626 -0.65500000000000003 -0.70199999999999996 0 0 0 125.2 10.45 24.55 142.19999999999999 26.01 15123 2012-01-30T20:00:00.000 RAW -0.626 -0.66400000000000003 -0.70199999999999996 0 0 0 125.7 12.73 31.41 145.5 27.52 15123 2012-01-30T21:00:00.000 RAW -0.626 -0.72 -0.73 0 0 0 125.4 11.51 25.81 148.6 25.65 15123 2012-01-30T22:00:00.000 RAW -0.626 -0.66400000000000003 -0.749 0 0 0 122.9 10.91 24.55 146.69999999999999 22.58 15123 2012-01-30T23:00:00.000 RAW -0.626 -0.79600000000000004 -0.80600000000000005 0 0 0 122.2 9.57 21.59 148.69999999999999 23.48 15123 2012-01-31T00:00:00.000 RAW -0.626 -0.89100000000000001 -0.91 0 0 0 125.6 9 20.65 147.5 23.59 15123 2012-01-31T01:00:00.000 RAW -0.626 -0.84399999999999997 -0.91 0 0 0 123.3 8.7100000000000009 23.29 148.9 25.03 15123 2012-01-31T02:00:00.000 RAW -0.626 -0.92 -0.93899999999999995 0 0 0 124.4 10.16 24.62 150.1 26.79 15123 2012-01-31T03:00:00.000 RAW -0.626 -0.93799999999999994 -0.96699999999999997 0 0 0 124.4 8.69 19.829999999999998 149.19999999999999 26.82 15123 2012-01-31T04:00:00.000 RAW -0.626 -1.0329999999999999 -1.0329999999999999 0 0 0 124.5 8.59 19.89 144 21.73 15123 2012-01-31T05:00:00.000 RAW -0.626 -1.27 -1.3169999999999999 0 0 0 123.6 7.52 16.12 144.19999999999999 19.97 15123 2012-01-31T06:00:00.000 ST -0.626 -1.2509999999999999 -1.3169999999999999 0 0 0 122.9 8.09 18.82 142.30000000000001 17.149999999999999 15123 2012-01-31T07:00:00.000 RAW -1.2509999999999999 -1.506 -1.506 0 0 1 123.8 10.14 18.89 143.4 20.059999999999999 15123 2012-01-31T08:00:00.000 RAW -1.2130000000000001 -1.2509999999999999 -1.506 0 0 1 123.3 10.18 21.34 137.9 17.739999999999998 15123 2012-01-31T09:00:00.000 RAW -0.92800000000000005 -0.92800000000000005 -1.506 0 0 2 124.5 9.61 22.22 141.69999999999999 19.78 15123 2012-01-31T10:00:00.000 RAW -0.65500000000000003 -0.65500000000000003 -1.506 0 0 4 126.1 8.33 18.260000000000002 147.5 18.79 15123 2012-01-31T11:00:00.000 RAW -0.248 -0.29499999999999998 -1.506 0 0 5 127.7 6.6 13.47 144.19999999999999 18.149999999999999 15123 2012-01-31T12:00:00.000 RAW -0.13500000000000001 -0.22 -1.506 0 0 5 127.6 7.93 16.87 143.5 16.52 15123 2012-01-31T13:00:00.000 RAW 8.3000000000000004E-2 -1.2E-2 -1.506 0 0 5 125.7 9.2200000000000006 18.190000000000001 140.80000000000001 18.88 15123 2012-01-31T14:00:00.000 RAW 8.3000000000000004E-2 -1.2E-2 -1.506 0 0 5 125.5 8.9700000000000006 22.66 144 24.62 15123 2012-01-31T15:00:00.000 RAW 0.16700000000000001 6.0000000000000001E-3 -1.506 0 0 5 125.7 7.72 18.57 142.30000000000001 22.11 15123 2012-01-31T16:00:00.000 RAW 0.16700000000000001 -0.249 -1.506 0 0 5 126 9.5299999999999994 21.59 145.30000000000001 19.079999999999998 15123 2012-01-31T17:00:00.000 RAW 0.16700000000000001 -0.33300000000000002 -1.506 0 0 5 126.3 6.5919999999999996 21.4 145.1 16.43 15123 2012-01-31T18:00:00.000 ST 0.16700000000000001 -0.40899999999999997 -1.506 0 0 5 126.1 3.5139999999999998 11.96 158 13.24 15123 2012-01-31T19:00:00.000 RAW -0.40899999999999997 -0.41799999999999998 -0.58899999999999997 0 0 0 125.9 3.2530000000000001 9.3800000000000008 163.5 14.98 15123 2012-01-31T20:00:00.000 RAW -0.33300000000000002 -0.371 -0.58899999999999997 0 0 0 117.5 4.0940000000000003 14.8 151.6 16.329999999999998 15123 2012-01-31T21:00:00.000 RAW -0.33300000000000002 -0.41799999999999998 -0.58899999999999997 0 0 0 123.9 3.9790000000000001 15.17 148 22.3 15123 2012-01-31T22:00:00.000 RAW -0.33300000000000002 -0.40799999999999997 -0.58899999999999997 0 0 0.1 126.2 2.8050000000000002 9.82 148.5 22.57 15123 2012-01-31T23:00:00.000 RAW -0.33300000000000002 -0.40899999999999997 -0.58899999999999997 0 0 0 118.1 2.2269999999999999 7.93 155.6 21.67 15123 2012-02-01T00:00:00.000 RAW -0.33300000000000002 -0.36099999999999999 -0.58899999999999997 0 0 0 121.4 1.96 9.07 156.1 18.64 15123 2012-02-01T01:00:00.000 RAW -0.33300000000000002 -0.371 -0.58899999999999997 0 0 0 121.6 0.71599999999999997 7.49 155.9 20.28 15123 2012-02-01T02:00:00.000 RAW -0.29499999999999998 -0.29499999999999998 -0.58899999999999997 0 0 0 123.4 0.65900000000000003 5.351 160.80000000000001 8.81 15123 2012-02-01T03:00:00.000 RAW -0.28599999999999998 -0.35199999999999998 -0.58899999999999997 0 0 3 128.4 0.89500000000000002 6.0439999999999996 176.5 7.05 15123 2012-02-01T04:00:00.000 RAW -0.28599999999999998 -0.34200000000000003 -0.58899999999999997 0 0 5 130.19999999999999 0.11600000000000001 2.0150000000000001 168.7 6.3540000000000001 15123 2012-02-01T05:00:00.000 RAW -0.28599999999999998 -0.34200000000000003 -0.58899999999999997 0 0 6 130.9 0.22700000000000001 4.0919999999999996 166.7 6.2069999999999999 15123 2012-02-01T06:00:00.000 ST -0.28599999999999998 -0.49399999999999999 -0.58899999999999997 0 0 7 131.5 0.29599999999999999 4.9109999999999996 176.3 4.6059999999999999 15123 2012-02-01T07:00:00.000 RAW -0.48399999999999999 -0.57899999999999996 -0.61699999999999999 0 0 0 131.19999999999999 0.376 4.6589999999999998 166.7 5.9169999999999998 15123 2012-02-01T08:00:00.000 RAW -0.48399999999999999 -0.94799999999999995 -0.95699999999999996 0 0 0 131.4 2.1070000000000002 9.44 167.8 10.18 15123 2012-02-01T09:00:00.000 RAW -0.48399999999999999 -1.014 -1.081 0 0 0 131.30000000000001 2.5270000000000001 8.31 157.80000000000001 13.32 15123 2012-02-01T10:00:00.000 RAW -0.46600000000000003 -0.59799999999999998 -1.081 0 0 0 131 0.50900000000000001 8.44 163.69999999999999 9.57 15123 2012-02-01T11:00:00.000 RAW -0.46600000000000003 -1.109 -1.1279999999999999 0 0 0 130.4 1.339 13.47 160.5 13.12 15123 2012-02-01T12:00:00.000 RAW 0.121 -0.17299999999999999 -1.1850000000000001 0 0 0 129.1 0.111 6.9240000000000004 172 15.44 15123 2012-02-01T13:00:00.000 RAW 0.121 -0.39100000000000001 -1.1850000000000001 0 0 0 129.30000000000001 0.38400000000000001 4.7839999999999998 164 8.34 15123 2012-02-01T14:00:00.000 RAW 0.121 -1.262 -1.262 0 0 0 128.6 1.4219999999999999 9.1300000000000008 148.1 17.149999999999999 15123 2012-02-01T15:00:00.000 RAW 0.121 -1.488 -1.5740000000000001 0 0 1 131.4 5.0650000000000004 14.86 143.19999999999999 22.2 15123 2012-02-01T16:00:00.000 RAW 0.121 -1.4690000000000001 -1.5740000000000001 0 0 1 131.4 4.2489999999999997 11.9 138.1 18.579999999999998 15123 2012-02-01T17:00:00.000 RAW 0.121 -1.7909999999999999 -1.8009999999999999 0 0 1 131.4 4.2480000000000002 13.16 145.4 19.38 15123 2012-02-01T18:00:00.000 ST 0.121 -1.923 -1.9330000000000001 0 0 2 131.30000000000001 4.1529999999999996 16.62 146.6 21.05 15123 2012-02-01T19:00:00.000 RAW -1.9139999999999999 -2.085 -2.085 0 0 0 131.30000000000001 3.6720000000000002 15.8 145.80000000000001 17.32 15123 2012-02-01T20:00:00.000 RAW -1.9139999999999999 -2.3690000000000002 -2.379 0 0 0 131.30000000000001 3.2250000000000001 12.02 147.30000000000001 17.5 15123 2012-02-01T21:00:00.000 RAW -1.9139999999999999 -2.4740000000000002 -2.4830000000000001 0 0 0 131.1 2.6779999999999999 9.9499999999999993 152.4 16.07 15123 2012-02-01T22:00:00.000 RAW -1.9139999999999999 -2.5489999999999999 -2.6349999999999998 0 0 0 131 2.5539999999999998 9.51 149.4 14.37 15123 2012-02-01T23:00:00.000 RAW -1.9139999999999999 -2.2450000000000001 -2.6349999999999998 0 0 0 130.9 1.8819999999999999 10.01 151.19999999999999 13.1 15123 2012-02-02T00:00:00.000 RAW -1.9139999999999999 -2.113 -2.6349999999999998 0 0 0 130.69999999999999 0.29599999999999999 3.274 155.19999999999999 8.08 15123 2012-02-02T01:00:00.000 RAW -1.9139999999999999 -2.093 -2.6349999999999998 0 0 0 130.6 1.08 4.9740000000000002 154.1 9.75 15123 2012-02-02T02:00:00.000 RAW -1.9139999999999999 -2.198 -2.6349999999999998 0 0 0 130.4 1.2689999999999999 10.89 151.9 15.97 15123 2012-02-02T03:00:00.000 RAW -1.9139999999999999 -2.331 -2.6349999999999998 0 0 0 130.30000000000001 0.95799999999999996 5.7290000000000001 151.1 11.24 15123 2012-02-02T04:00:00.000 RAW -1.9139999999999999 -2.331 -2.6349999999999998 0 0 0 130.1 1.59 6.4219999999999997 151.4 14.4 15123 2012-02-02T05:00:00.000 RAW -1.9139999999999999 -2.4540000000000002 -2.6349999999999998 0 0 0 129.9 0.83899999999999997 5.8550000000000004 152 9.35 15123 2012-02-02T06:00:00.000 ST -1.9139999999999999 -2.6349999999999998 -2.645 0 0 0 129.69999999999999 0.97399999999999998 5.54 157.5 11.96 15123 2012-02-02T07:00:00.000 RAW -2.625 -2.7589999999999999 -2.7589999999999999 0 0 0 129.30000000000001 0.82 6.4850000000000003 152.9 13.67 15123 2012-02-02T08:00:00.000 RAW -2.492 -2.5019999999999998 -2.7869999999999999 0 0 0 129.1 0.57699999999999996 6.0439999999999996 171.2 8.89 15123 2012-02-02T09:00:00.000 RAW -1.97 -1.97 -2.7869999999999999 0 0 0 128.9 4.5999999999999999E-2 2.141 173.5 2.6520000000000001 15123 2012-02-02T10:00:00.000 RAW -0.85299999999999998 -0.93799999999999994 -2.7869999999999999 0 0 0 128.5 2E-3 0.126 184.7 0.33300000000000002 15123 2012-02-02T11:00:00.000 RAW 0.19700000000000001 9.2999999999999999E-2 -2.7869999999999999 0 0 0 127.7 0 6.3E-2 187.2 1.9E-2 15123 2012-02-02T12:00:00.000 RAW 0.67800000000000005 0.67800000000000005 -2.7869999999999999 0 0 0 127.5 0 0 0 0 15123 2012-02-02T13:00:00.000 RAW 1.3480000000000001 1.3480000000000001 -2.7869999999999999 0 0 0 126.1 0 0 0 0 15123 2012-02-02T14:00:00.000 RAW 2.0859999999999999 1.821 -2.7869999999999999 0 0 0 126.6 0 0 0 0 15123 2012-02-02T15:00:00.000 RAW 2.0859999999999999 0.372 -2.7869999999999999 0 0 0 126.1 1E-3 0.189 345 0.99299999999999999 15123 2012-02-02T16:00:00.000 RAW 2.0859999999999999 -0.47799999999999998 -2.7869999999999999 0 0 0 126.1 4.1000000000000002E-2 1.573 26.8 3.7589999999999999 15123 2012-02-02T17:00:00.000 RAW 2.0859999999999999 -1.3859999999999999 -2.7869999999999999 0 0 0 125 2.9580000000000002 7.68 23.83 11.48 15123 2012-02-02T18:00:00.000 ST 2.0859999999999999 -1.7529999999999999 -2.7869999999999999 0 0 0 123.1 3.3690000000000002 12.15 34.17 21.03 15123 2012-02-02T19:00:00.000 RAW -1.7529999999999999 -1.8759999999999999 -2.0179999999999998 0 0 0 123.2 8.99 16.940000000000001 24.63 18.8 15123 2012-02-02T20:00:00.000 RAW -1.7529999999999999 -2.2549999999999999 -2.331 0 0 0 122.8 8.1999999999999993 15.24 25.72 16.53 15123 2012-02-02T21:00:00.000 RAW -1.7529999999999999 -2.5680000000000001 -2.5680000000000001 0 0 0 122.8 4.077 11.33 12.8 24.95 15123 2012-02-02T22:00:00.000 RAW -1.7529999999999999 -2.6160000000000001 -2.7389999999999999 0 0 0 122.6 2.298 6.6740000000000004 14.45 20.71 15123 2012-02-02T23:00:00.000 RAW -1.7529999999999999 -2.73 -2.74 0 0 0 123 3.4990000000000001 10.7 11.48 28.58 15123 2012-02-03T00:00:00.000 RAW -1.7529999999999999 -2.948 -3.0720000000000001 0 0 0 122.9 4.2549999999999999 12.34 8.94 27.24 15123 2012-02-03T01:00:00.000 RAW -1.7529999999999999 -3.4529999999999998 -3.4540000000000002 0 0 0.1 123.2 2.855 9.6300000000000008 4.7990000000000004 25.28 15123 2012-02-03T02:00:00.000 RAW -1.7529999999999999 -2.8340000000000001 -3.492 0 0 0 122.2 5.35 13.92 16.29 21.29 15123 2012-02-03T03:00:00.000 RAW -1.7529999999999999 -2.6920000000000002 -3.492 0 0 1 123.5 7.12 18.829999999999998 17.23 24.63 15123 2012-02-03T04:00:00.000 RAW -1.7529999999999999 -2.9860000000000002 -3.492 0 0 1 123.3 7.55 16.309999999999999 14.66 19.89 15123 2012-02-03T05:00:00.000 RAW -1.7529999999999999 -2.6629999999999998 -3.492 0 0 2 124.5 9.89 22.54 16.32 20.309999999999999 15123 2012-02-03T06:00:00.000 ST -1.7529999999999999 -2.7959999999999998 -3.492 0 0 3 125.4 11.34 23.8 19.690000000000001 19.670000000000002 15123 2012-02-03T07:00:00.000 RAW -2.7959999999999998 -2.9580000000000002 -3.52 0 0 1 126.3 10.74 21.16 17.43 17.34 15123 2012-02-03T08:00:00.000 RAW -2.7959999999999998 -3.2240000000000002 -3.96 0 0 1 126 9.92 22.1 14.38 20.83 15123 2012-02-03T09:00:00.000 RAW -2.7959999999999998 -3.0720000000000001 -3.96 0 0 1 126.4 11.25 18.89 15.59 18.38 15123 2012-02-03T10:00:00.000 RAW -1.96 -1.9890000000000001 -3.96 0 0 1 126 9.77 21.28 18.45 29.15 15123 2012-02-03T11:00:00.000 RAW -1.2689999999999999 -1.2969999999999999 -3.96 0 0 1 125.2 11.6 19.77 25.55 22.86 15123 2012-02-03T12:00:00.000 RAW 0.55600000000000005 0.55600000000000005 -3.96 0 0 1 124.8 10.08 24.18 19.7 22.7 15123 2012-02-03T13:00:00.000 RAW 2.1240000000000001 1.3460000000000001 -3.96 0 0 1 125 9.17 20.71 19.489999999999998 25.26 15123 2012-02-03T14:00:00.000 RAW 2.9740000000000002 2.9740000000000002 -3.96 0 0 1 124.6 4.0419999999999998 13.39 16.920000000000002 23.35 15123 2012-02-03T15:00:00.000 RAW 4.0960000000000001 2.8050000000000002 -3.96 0 0 1 124.6 2.3170000000000002 9.8699999999999992 22.96 16.95 15123 2012-02-03T16:00:00.000 RAW 4.0960000000000001 2.6920000000000002 -3.96 0 0 1 124.9 4.8310000000000004 15.1 28.37 18.43 15123 2012-02-03T17:00:00.000 RAW 4.0960000000000001 0.16600000000000001 -3.96 0 0 1 124.9 9.27 15.41 24.73 14.98 15123 2012-02-03T18:00:00.000 ST 4.0960000000000001 0.67900000000000005 -3.96 0 0 1 124.5 10.26 15.98 27.53 15.1 15123 2012-02-03T19:00:00.000 RAW 0.86899999999999999 0.5 0.5 0 0 0 124.5 10.039999999999999 17.37 23 14.23 15123 2012-02-03T20:00:00.000 RAW 0.86899999999999999 -4.9000000000000002E-2 -4.9000000000000002E-2 0 0 1 125.4 9.2100000000000009 14.48 29.53 12.96 15123 2012-02-03T21:00:00.000 RAW 0.86899999999999999 -0.63500000000000001 -0.63500000000000001 0 0 1 125.5 5.9059999999999997 10.199999999999999 24.36 9.64 15123 2012-02-03T22:00:00.000 RAW 0.86899999999999999 -1.3260000000000001 -1.3260000000000001 0 0 2 126.5 3.867 7.81 19.93 11.07 15123 2012-02-03T23:00:00.000 RAW 0.86899999999999999 -1.629 -1.6479999999999999 0 0 2 126.3 0.57299999999999995 4.7850000000000001 2.6 12.77 15123 2012-02-04T00:00:00.000 RAW 0.86899999999999999 -2.2069999999999999 -2.2160000000000002 0 0 2 126.4 1.8029999999999999 10.95 23.76 17.25 15123 2012-02-04T01:00:00.000 RAW 0.86899999999999999 -2.0840000000000001 -2.226 0 0 2 126.2 2.54 6.548 16.760000000000002 15.74 15123 2012-02-04T02:00:00.000 RAW 0.86899999999999999 -2.169 -2.274 0 0 3 126.5 3.7440000000000002 7.81 28.6 11.47 15123 2012-02-04T03:00:00.000 RAW 0.86899999999999999 -2.673 -2.7869999999999999 0 0 3 126.4 0.61699999999999999 5.9180000000000001 29.41 8.44 15123 2012-02-04T04:00:00.000 RAW 0.86899999999999999 -2.653 -2.7869999999999999 0 0 3 126.3 3.0880000000000001 8.5 28.78 9.8699999999999992 15123 2012-02-04T05:00:00.000 RAW 0.86899999999999999 -3.0630000000000002 -3.0720000000000001 0 0 3 126.2 3.33 7.81 31.26 12.56 15123 2012-02-04T06:00:00.000 ST 0.86899999999999999 -2.996 -3.3010000000000002 0 0 3 125.9 1.4550000000000001 6.8639999999999999 23.45 9.68 15123 2012-02-04T07:00:00.000 RAW -2.996 -3.282 -3.2909999999999999 0 0 0 125 0.53900000000000003 4.7229999999999999 16.77 4.0449999999999999 15123 2012-02-04T08:00:00.000 RAW -2.996 -3.6539999999999999 -3.7210000000000001 0 0 0 124 4.7939999999999996 10.89 22.8 12.5 15123 2012-02-04T09:00:00.000 RAW -2.996 -3.8159999999999998 -3.94 0 0 0 122.8 1.425 6.9269999999999996 3.153 29.8 15123 2012-02-04T10:00:00.000 RAW -2.996 -3.3490000000000002 -3.94 0 0 0 123.4 3.294 13.54 15.5 23.64 15123 2012-02-04T11:00:00.000 RAW -2.3879999999999999 -2.5590000000000002 -3.94 0 0 1 126.1 9.06 19.21 21.86 21.38 15123 2012-02-04T12:00:00.000 RAW 0.5 0.5 -3.94 0 0 1 125.6 8.36 19.010000000000002 23.22 23.35 15123 2012-02-04T13:00:00.000 RAW 1.1319999999999999 0.48499999999999999 -3.94 0 0 1 125.8 11.35 23.16 28.24 19.87 15123 2012-02-04T14:00:00.000 RAW 1.9319999999999999 1.9319999999999999 -3.94 0 0 1 125.1 11.9 21.69 23.4 23.3 15123 2012-02-04T15:00:00.000 RAW 2.2069999999999999 1.2709999999999999 -3.94 0 0 1 125.9 11.01 22.64 13.82 26.44 15123 2012-02-04T16:00:00.000 RAW 2.6739999999999999 2.6739999999999999 -3.94 0 0 1 125.1 11.4 23.97 21.51 24.79 15123 2012-02-04T17:00:00.000 RAW 2.8919999999999999 0.48799999999999999 -3.94 0 0 1 125.9 10.83 22.77 19.670000000000002 20.99 15123 2012-02-04T18:00:00.000 ST 2.8919999999999999 -0.30499999999999999 -3.94 0 0 1 126.2 7.41 17.239999999999998 23.19 24.73 15123 2012-02-04T19:00:00.000 RAW 0.23499999999999999 0.122 -0.48399999999999999 0 0 0 125.7 7.06 16.05 24.28 20.94 15123 2012-02-04T20:00:00.000 RAW 0.23499999999999999 -0.60699999999999998 -0.60699999999999998 0 0 0 125.7 6.8970000000000002 11.9 27.31 11.93 15123 2012-02-04T21:00:00.000 RAW 0.23499999999999999 -1.591 -1.591 0 0 0 125.7 2.004 7.24 16.940000000000001 15.8 15123 2012-02-04T22:00:00.000 RAW 0.23499999999999999 -2.1219999999999999 -2.226 0 0 0 126 1.966 7.18 16.149999999999999 26.9 15123 2012-02-04T23:00:00.000 RAW 0.23499999999999999 -2.6539999999999999 -2.6920000000000002 0 0 0 126 4.8220000000000001 9.07 25.19 11.87 15123 2012-02-05T00:00:00.000 RAW 0.23499999999999999 -2.5590000000000002 -2.6920000000000002 0 0 0 125.8 3.9969999999999999 8 26.18 15.47 15123 2012-02-05T01:00:00.000 RAW 0.23499999999999999 -3.3490000000000002 -3.3490000000000002 0 0 0.1 126.2 2.5819999999999999 8.44 28.63 10.98 15123 2012-02-05T02:00:00.000 RAW 0.23499999999999999 -3.31 -3.3959999999999999 0 0 0 125.7 0.35399999999999998 5.4779999999999998 23.47 7.94 15123 2012-02-05T03:00:00.000 RAW 0.23499999999999999 -3.7869999999999999 -3.8159999999999998 0 0 0 125.8 0 0 0 0 15123 2012-02-05T04:00:00.000 RAW 0.23499999999999999 -3.9590000000000001 -3.9590000000000001 0 0 0.1 126 0 6.3E-2 15.3 3.0000000000000001E-3 15123 2012-02-05T05:00:00.000 RAW 0.23499999999999999 -3.9870000000000001 -4.17 0 0 0.1 125.9 0 0 0 0 15123 2012-02-05T06:00:00.000 ST 0.23499999999999999 -4.1689999999999996 -4.2649999999999997 0 0 0 125.5 0 0 0 0 15123 2012-02-05T07:00:00.000 RAW -4.1689999999999996 -4.3710000000000004 -4.476 0 0 0.1 125.8 0 0 0 0 15123 2012-02-05T08:00:00.000 RAW -4.1020000000000003 -4.4089999999999998 -4.5720000000000001 0 0 0 125.5 1E-3 0.252 17.170000000000002 4.9969999999999999 15123 2012-02-05T09:00:00.000 RAW -3.9590000000000001 -4.1500000000000004 -4.5720000000000001 0 0 0 125.4 0.01 1.008 9.4700000000000006 1.516 15123 2012-02-05T10:00:00.000 RAW -2.681 -2.7 -4.5720000000000001 0 0 0 125.3 0.217 3.3380000000000001 13 16.41 15123 2012-02-05T11:00:00.000 RAW -1.61 -1.61 -4.5720000000000001 0 0 0.1 125.6 0.48799999999999999 6.8019999999999996 32.54 12.8 15123 2012-02-05T12:00:00.000 RAW 1.6160000000000001 1.6160000000000001 -4.5720000000000001 0 0 0 124.1 4.9000000000000002E-2 3.1480000000000001 3.7309999999999999 13.56 15123 2012-02-05T13:00:00.000 RAW 3.0819999999999999 2.472 -4.5720000000000001 0 0 0 124 9.6000000000000002E-2 3.524 343.3 5.4420000000000002 15123 2012-02-05T14:00:00.000 RAW 3.0819999999999999 2.5369999999999999 -4.5720000000000001 0 0 0 124.4 0.33300000000000002 7.17 333.5 11.73 15123 2012-02-05T15:00:00.000 RAW 3.0819999999999999 1.9039999999999999 -4.5720000000000001 0 0 0 124.8 4.1000000000000002E-2 2.641 343.2 4.5279999999999996 15123 2012-02-05T16:00:00.000 RAW 3.0819999999999999 0.36299999999999999 -4.5720000000000001 0 0 0 125.2 3.4319999999999999 10.5 28.98 11.43 15123 2012-02-05T17:00:00.000 RAW 3.0819999999999999 -1.9450000000000001 -4.5720000000000001 0 0 0 124.8 9.39 17.489999999999998 37.200000000000003 18.04 15123 2012-02-05T18:00:00.000 ST 3.0819999999999999 -1.611 -4.5720000000000001 0 0 0.1 125.4 7.83 17.239999999999998 28.48 21.19 15123 2012-02-05T19:00:00.000 RAW -1.4590000000000001 -1.7909999999999999 -1.81 0 0 0 124.9 6.4660000000000002 14.35 15.86 23.36 15123 2012-02-05T20:00:00.000 RAW -1.4590000000000001 -1.734 -2.198 0 0 0 124.7 8.17 14.35 12.19 25.11 15123 2012-02-05T21:00:00.000 RAW -1.345 -1.639 -2.198 0 0 0 124.6 10.220000000000001 18.95 25.88 23.14 15123 2012-02-05T22:00:00.000 RAW -1.345 -2.4449999999999998 -2.5209999999999999 0 0 0 124.5 12.62 22.66 24.99 19.850000000000001 15123 2012-02-05T23:00:00.000 RAW -1.345 -3.359 -3.569 0 0 0 124.7 9.43 16.43 13.28 23.71 15123 2012-02-06T00:00:00.000 RAW -1.345 -3.8740000000000001 -3.8740000000000001 0 0 0 124.7 10.24 17.63 14.23 22.96 15123 2012-02-06T01:00:00.000 RAW -1.345 -3.548 -4.1989999999999998 0 0 0 124.6 10.75 20.46 14.83 22.05 15123 2012-02-06T02:00:00.000 RAW -1.345 -3.4529999999999998 -4.1989999999999998 0 0 0 124.9 13.33 25 15.62 22.35 15123 2012-02-06T03:00:00.000 RAW -1.345 -4.141 -4.1989999999999998 0 0 0 124.7 12.47 29.79 16.899999999999999 25.44 15123 2012-02-06T04:00:00.000 RAW -1.345 -4.3330000000000002 -4.4669999999999996 0 0 0 124.6 12.19 26.95 15.15 24.41 15123 2012-02-06T05:00:00.000 RAW -1.345 -3.6720000000000002 -4.4669999999999996 0 0 0 124.5 14.02 27.46 17.27 22.47 15123 2012-02-06T06:00:00.000 ST -1.345 -3.6150000000000002 -4.4669999999999996 0 0 0 124.5 14.37 23.68 21.77 18.510000000000002 15123 2012-02-06T07:00:00.000 RAW -3.472 -5.0730000000000004 -5.0830000000000002 0 0 0 124.4 13.85 22.17 26.77 18.57 15123 2012-02-06T08:00:00.000 RAW -3.472 -5.1790000000000003 -5.3719999999999999 0 0 0 124.3 13.73 19.899999999999999 28.54 17.149999999999999 15123 2012-02-06T09:00:00.000 RAW -3.472 -5.391 -5.391 0 0 0 124.4 13.01 23.74 20.8 19.100000000000001 15123 2012-02-06T10:00:00.000 RAW -3.472 -5.6239999999999997 -5.6239999999999997 0 0 0 124.5 12.22 22.61 16.02 21.46 15123 2012-02-06T11:00:00.000 RAW -3.472 -3.53 -5.6239999999999997 0 0 0 124.4 10.51 19.329999999999998 15.04 25.1 15123 2012-02-06T12:00:00.000 RAW 0.55700000000000005 0.51 -5.6239999999999997 0 0 0 123.7 12.29 24.49 17.850000000000001 22.05 15123 2012-02-06T13:00:00.000 RAW 1.8220000000000001 1.3839999999999999 -5.6239999999999997 0 0 0 123.5 13.36 28.31 25.7 24.68 15123 2012-02-06T14:00:00.000 RAW 2.5190000000000001 2.5089999999999999 -5.6239999999999997 0 0 0 123.3 10.16 25.46 15.01 26.95 15123 2012-02-06T15:00:00.000 RAW 2.8220000000000001 1.9330000000000001 -5.6239999999999997 0 0 0 124 6.867 17.48 9.5500000000000007 30.94 15123 2012-02-06T16:00:00.000 RAW 3.2709999999999999 3.2610000000000001 -5.6239999999999997 0 0 0 123.7 8.83 21.13 358.2 29.3 15123 2012-02-06T17:00:00.000 RAW 3.2709999999999999 0.50600000000000001 -5.6239999999999997 0 0 1 124.6 10.84 23.72 12.4 21.94 15123 2012-02-06T18:00:00.000 ST 3.2709999999999999 0.58399999999999996 -5.6239999999999997 0 0 1 124.5 11.52 21.77 25.37 20.399999999999999 15123 2012-02-06T19:00:00.000 RAW 0.58399999999999996 -1.0049999999999999 -1.2130000000000001 0 0 0 124.5 9.5 17.25 14.62 24.61 15123 2012-02-06T20:00:00.000 RAW 0.58399999999999996 0.216 -1.2130000000000001 0 0 0 124.5 12.3 23.04 20.059999999999999 19.940000000000001 15123 2012-02-06T21:00:00.000 RAW 0.58399999999999996 -0.71099999999999997 -1.2130000000000001 0 0 0 124.2 11.33 21.59 26.49 22.5 15123 2012-02-06T22:00:00.000 RAW 0.58399999999999996 -1.004 -1.5820000000000001 0 0 0.1 124.7 10.88 21.22 30.78 20.83 15123 2012-02-06T23:00:00.000 RAW 0.58399999999999996 -0.114 -1.5820000000000001 0 0 0 124.5 12.97 24.05 26.5 19.5 15123 2012-02-07T00:00:00.000 RAW 0.58399999999999996 -1E-3 -1.5820000000000001 0 0 0 124.5 11.7 20.079999999999998 23.07 23.32 15123 2012-02-07T01:00:00.000 RAW 0.58399999999999996 -1.8 -1.819 0 0 0 124 10.119999999999999 18.95 25.68 20.73 15123 2012-02-07T02:00:00.000 RAW 0.58399999999999996 -3.6160000000000001 -4.9870000000000001 0 0 0.1 124.4 7.83 18.07 15.91 27.52 15123 2012-02-07T03:00:00.000 RAW 0.58399999999999996 -2.5960000000000001 -4.9870000000000001 0 0 0 124.2 7.82 20.28 15.92 26.69 15123 2012-02-07T04:00:00.000 RAW 0.58399999999999996 -3.0910000000000002 -4.9870000000000001 0 0 0 124 9.44 19.96 12.7 24.13 15123 2012-02-07T05:00:00.000 RAW 0.58399999999999996 -2.4630000000000001 -4.9870000000000001 0 0 0.1 124.3 9.98 19.329999999999998 14.29 25.21 15123 2012-02-07T06:00:00.000 ST 0.58399999999999996 -2.4630000000000001 -4.9870000000000001 0 0 0 123.9 10.77 21.72 20.79 22.03 15123 2012-02-07T07:00:00.000 RAW -2.4630000000000001 -4.9859999999999998 -5.8179999999999996 0 0 0 123.9 9.83 22.98 15.05 24.83 15123 2012-02-07T08:00:00.000 RAW -2.4630000000000001 -3.0049999999999999 -5.9729999999999999 0 0 0.1 124.2 10.57 19.71 18.32 20.74 15123 2012-02-07T09:00:00.000 RAW -2.4630000000000001 -3.7679999999999998 -5.9729999999999999 0 0 0 123.9 11.3 19.84 18.54 19.79 15123 2012-02-07T10:00:00.000 RAW -2.2349999999999999 -2.2349999999999999 -5.9729999999999999 0 0 0 123.9 11.73 24.43 18.600000000000001 20.74 15123 2012-02-07T11:00:00.000 RAW -1.004 -1.004 -5.9729999999999999 0 0 0.1 124 12.08 23.74 27.57 19.78 15123 2012-02-07T12:00:00.000 RAW 1.2470000000000001 1.2370000000000001 -5.9729999999999999 0 0 0 123.1 11.45 24.81 29.88 22.01 15123 2012-02-07T13:00:00.000 RAW 2.4249999999999998 1.714 -5.9729999999999999 0 0 0 123 10.68 27.57 23.11 24.74 15123 2012-02-07T14:00:00.000 RAW 3.5139999999999998 3.5139999999999998 -5.9729999999999999 0 0 0 123.7 8.56 17.98 20.81 20.75 15123 2012-02-07T15:00:00.000 RAW 4.1420000000000003 2.2730000000000001 -5.9729999999999999 0 0 1 124.4 7.1 15.97 16.32 22.83 15123 2012-02-07T16:00:00.000 RAW 4.1420000000000003 3.45 -5.9729999999999999 0 0 1 122.9 8.92 19.309999999999999 19.18 20.11 15123 2012-02-07T17:00:00.000 RAW 4.1420000000000003 0.86599999999999999 -5.9729999999999999 0 0 1 124.4 9.92 18.68 24.7 20.2 15123 2012-02-07T18:00:00.000 ST 4.1420000000000003 0.55500000000000005 -5.9729999999999999 0 0 1 124.7 8.81 15.79 29.5 17.09 15123 2012-02-07T19:00:00.000 RAW 0.55500000000000005 7.3999999999999996E-2 -0.20100000000000001 0 0 0 124.1 8.61 17.43 30.52 18.329999999999998 15123 2012-02-07T20:00:00.000 RAW 0.55500000000000005 -1.4119999999999999 -1.5920000000000001 0 0 0 124.1 8.75 14.67 26.57 15.82 15123 2012-02-07T21:00:00.000 RAW 0.55500000000000005 -2.2549999999999999 -2.2839999999999998 0 0 0 124 5.0789999999999997 12.72 15.86 21.95 15123 2012-02-07T22:00:00.000 RAW 0.55500000000000005 -2.0270000000000001 -2.2839999999999998 0 0 0 124 3.6720000000000002 9.57 20.23 24.28 15123 2012-02-07T23:00:00.000 RAW 0.55500000000000005 -2.1219999999999999 -2.2839999999999998 0 0 0 124.1 4.7569999999999997 9.3800000000000008 31.13 10.23 15123 2012-02-08T00:00:00.000 RAW 0.55500000000000005 -2.597 -2.597 0 0 0 124.1 1.8919999999999999 5.7290000000000001 23.45 13.8 15123 2012-02-08T01:00:00.000 RAW 0.55500000000000005 -2.92 -2.9580000000000002 0 0 0 124.4 0.20100000000000001 2.4550000000000001 17.059999999999999 3.96 15123 2012-02-08T02:00:00.000 RAW 0.55500000000000005 -2.9580000000000002 -3.149 0 0 0 124.4 0 6.3E-2 9.5500000000000007 0 15123 2012-02-08T03:00:00.000 RAW 0.55500000000000005 -2.8439999999999999 -3.149 0 0 0 124.2 1E-3 0.378 18.89 1.2999999999999999E-2 15123 2012-02-08T04:00:00.000 RAW 0.55500000000000005 -2.3109999999999999 -3.149 0 0 0 124.1 0 0.126 15.65 3.7549999999999999 15123 2012-02-08T05:00:00.000 RAW 0.55500000000000005 -1.9890000000000001 -3.149 0 0 0 124 0 0 0 0 15123 2012-02-08T06:00:00.000 ST 0.55500000000000005 -1.4770000000000001 -3.149 0 0 0 123.9 0 0 0 0 15123 2012-02-08T07:00:00.000 RAW -1.4770000000000001 -1.534 -1.629 0 0 0 123.9 0 6.3E-2 10.130000000000001 0 15123 2012-02-08T08:00:00.000 RAW -1.212 -1.212 -1.629 0 0 0 123.7 0 0 0 0 15123 2012-02-08T09:00:00.000 RAW -0.96599999999999997 -0.96599999999999997 -1.629 0 0 0 123.8 0 6.3E-2 141.1 0 15123 2012-02-08T10:00:00.000 RAW 1.048 1.0289999999999999 -1.629 0 0 0 123 3.0000000000000001E-3 0.252 166.4 5.5019999999999998 15123 2012-02-08T11:00:00.000 RAW 2.8180000000000001 2.8180000000000001 -1.629 0 0 0 123.2 1E-3 0.252 180.1 5.5E-2 15123 2012-02-08T12:00:00.000 RAW 4.3550000000000004 3.8319999999999999 -1.629 0 0 0 122.4 3.8370000000000002 14.1 173.6 15.14 15123 2012-02-08T13:00:00.000 RAW 4.8220000000000001 4.4489999999999998 -1.629 0 0 0 122.5 0.16700000000000001 4.0270000000000001 181.4 31.44 15123 2012-02-08T14:00:00.000 RAW 5.3920000000000003 5.3630000000000004 -1.629 0 0 0 121.4 1E-3 0.252 327.2 0 15123 2012-02-08T15:00:00.000 RAW 5.3920000000000003 4.3899999999999997 -1.629 0 0 0 122.6 5.0000000000000001E-3 0.56599999999999995 196.2 1.6519999999999999 15123 2012-02-08T16:00:00.000 RAW 5.3920000000000003 2.8039999999999998 -1.629 0 0 0 122.5 1.4E-2 1.5089999999999999 159.9 0.45300000000000001 15123 2012-02-08T17:00:00.000 RAW 5.3920000000000003 1.47 -1.629 0 0 0 121.3 0.16 3.27 172.3 4.0419999999999998 15123 2012-02-08T18:00:00.000 ST 5.3920000000000003 0.60099999999999998 -1.629 0 0 0 122.3 4.6349999999999998 13.78 130.5 14.12 15123 2012-02-08T19:00:00.000 RAW 0.64 0.63100000000000001 2.5000000000000001E-2 0 0 0 122.1 3.8050000000000002 13.28 147.30000000000001 18.07 15123 2012-02-08T20:00:00.000 RAW 1.0469999999999999 0.80100000000000005 2.5000000000000001E-2 0 0 0 122.2 3.7879999999999998 12.78 154.5 13.39 15123 2012-02-08T21:00:00.000 RAW 1.0469999999999999 0.65 2.5000000000000001E-2 0 0 0 122.3 0.20200000000000001 4.468 165.1 9.5500000000000007 15123 2012-02-08T22:00:00.000 RAW 1.0469999999999999 0.36599999999999999 2.5000000000000001E-2 0 0 0 122.3 3.4140000000000001 10.07 153.30000000000001 15.65 15123 2012-02-08T23:00:00.000 RAW 1.0469999999999999 0.83 2.5000000000000001E-2 0 0 0 122.2 0.92800000000000005 6.6710000000000003 169.9 11.15 15123 2012-02-09T00:00:00.000 RAW 1.0469999999999999 0.54600000000000004 2.5000000000000001E-2 0 0 0 122 0.52200000000000002 4.1539999999999999 169.2 10.06 15123 2012-02-09T01:00:00.000 RAW 1.0469999999999999 -0.35199999999999998 -0.36199999999999999 0 0 0 121.9 8.5000000000000006E-2 2.8319999999999999 168.7 9.23 15123 2012-02-09T02:00:00.000 RAW 1.0469999999999999 -0.04 -0.42799999999999999 0 0 0 121.6 1.4E-2 1.196 188.2 1.5589999999999999 15123 2012-02-09T03:00:00.000 RAW 1.0469999999999999 0.14899999999999999 -0.42799999999999999 0 0 0 121.5 2E-3 0.378 30.18 0.66100000000000003 15123 2012-02-09T04:00:00.000 RAW 1.0469999999999999 0.121 -0.42799999999999999 0 0 0 121.4 0 0.252 338.4 1.321 15123 2012-02-09T05:00:00.000 RAW 1.0469999999999999 -0.34300000000000003 -0.42799999999999999 0 0 0 121.5 1.2E-2 1.2589999999999999 333.4 0.23300000000000001 15123 2012-02-09T06:00:00.000 ST 1.0469999999999999 -0.38 -0.42799999999999999 0 0 0 121.4 0 0 0 0 15123 2012-02-09T07:00:00.000 RAW -0.219 -0.219 -0.42799999999999999 0 0 0 121.4 2E-3 0.189 15.78 3.5150000000000001 15123 2012-02-09T08:00:00.000 RAW -5.8999999999999997E-2 -0.38 -0.46600000000000003 0 0 0 121.4 0.35899999999999999 3.903 21.56 8.5500000000000007 15123 2012-02-09T09:00:00.000 RAW 0.13 0.13 -0.46600000000000003 0 0 0 121.5 0.06 2.58 15.21 12.47 15123 2012-02-09T10:00:00.000 RAW 1.1319999999999999 1.1319999999999999 -0.46600000000000003 0 0 0 121.4 0.26700000000000002 2.7690000000000001 19.670000000000002 10.97 15123 2012-02-09T11:00:00.000 RAW 1.5289999999999999 1.51 -0.46600000000000003 0 0 0 121.3 0.01 1.448 41.76 7.97 15123 2012-02-09T12:00:00.000 RAW 2.74 2.702 -0.46600000000000003 0 0 0 121 0 0 0 0 15123 2012-02-09T13:00:00.000 RAW 3.375 3.375 -0.46600000000000003 0 0 0 120.9 0 6.3E-2 358.1 0 15123 2012-02-09T14:00:00.000 RAW 3.84 3.2410000000000001 -0.46600000000000003 0 0 0 120.5 0 0 0 0 15123 2012-02-09T15:00:00.000 RAW 3.84 2.8239999999999998 -0.46600000000000003 0 0 0 120.1 0 0 0 0 15123 2012-02-09T16:00:00.000 RAW 3.84 2.3879999999999999 -0.46600000000000003 0 0 0 120.6 0 0 0 0 15123 2012-02-09T17:00:00.000 RAW 3.84 1.7170000000000001 -0.46600000000000003 0 0 0 120.7 8.0000000000000002E-3 0.81799999999999995 149.1 3.649 15123 2012-02-09T18:00:00.000 ST 3.84 1.585 -0.46600000000000003 0 0 0 120.9 0.13600000000000001 3.5859999999999999 175.2 2.4119999999999999 15123 2012-02-09T19:00:00.000 RAW 2.3809999999999998 2.3340000000000001 1.5760000000000001 0 0 0 120.7 2.8000000000000001E-2 0.94399999999999995 110.3 1.601 15123 2012-02-09T20:00:00.000 RAW 2.3809999999999998 1.9079999999999999 1.5760000000000001 0 0 0 120.8 0 6.3E-2 311.3 3.254 15123 2012-02-09T21:00:00.000 RAW 2.3809999999999998 1.87 1.5760000000000001 0 0 0 120.7 0 0 0 0 15123 2012-02-09T22:00:00.000 RAW 2.3809999999999998 1.7190000000000001 1.5760000000000001 0 0 0 120.4 0 6.3E-2 62.07 3.9E-2 15123 2012-02-09T23:00:00.000 RAW 2.3809999999999998 1.851 1.5760000000000001 0 0 0 120.4 0 0 0 0 15123 2012-02-10T00:00:00.000 RAW 2.3809999999999998 1.738 1.5760000000000001 0 0 0 120.2 3.3000000000000002E-2 2.3279999999999998 24.35 0.98599999999999999 15123 2012-02-10T01:00:00.000 RAW 2.3809999999999998 1.681 1.5760000000000001 0 0 0 119.8 0.33800000000000002 8.5 347.8 12.93 15123 2012-02-10T02:00:00.000 RAW 2.3809999999999998 1.4350000000000001 1.2549999999999999 0 0 0 119.3 0.44900000000000001 5.726 352.2 13.69 15123 2012-02-10T03:00:00.000 RAW 2.3809999999999998 0.36599999999999999 0.32800000000000001 0 0 0 119.2 2.66 10.32 26.79 17.010000000000002 15123 2012-02-10T04:00:00.000 RAW 2.3809999999999998 0.67800000000000005 0.20499999999999999 0 0 0 119 2.1070000000000002 7.99 31.6 20.65 15123 2012-02-10T05:00:00.000 RAW 2.3809999999999998 -7.8E-2 -0.13500000000000001 0 0 0 118.9 3.6080000000000001 11.27 23.31 10.97 15123 2012-02-10T06:00:00.000 ST 2.3809999999999998 0.376 -0.13500000000000001 0 0 0 118.9 2.7069999999999999 11.33 27.55 16.55 15123 2012-02-10T07:00:00.000 RAW 0.41399999999999998 -3.0000000000000001E-3 -1.2E-2 0 0 0 118.8 0.13700000000000001 3.5870000000000002 14.06 8.83 15123 2012-02-10T08:00:00.000 RAW 0.41399999999999998 0.32900000000000001 -0.05 0 0 0 119 2.8000000000000001E-2 1.825 4.1360000000000001 9.2799999999999994 15123 2012-02-10T09:00:00.000 RAW 1.208 1.208 -0.05 0 0 0 118.8 0 0.126 83.3 2.5999999999999999E-2 15123 2012-02-10T10:00:00.000 RAW 2.1259999999999999 2.1259999999999999 -0.05 0 0 0 118.3 0 6.3E-2 358.3 1E-3 15123 2012-02-10T11:00:00.000 RAW 2.95 2.76 -0.05 0 0 0 118.7 1E-3 0.126 356.9 2.86 15123 2012-02-10T12:00:00.000 RAW 2.95 2.379 -0.05 0 0 0 118.5 6.0000000000000001E-3 0.56599999999999995 332.7 0.50600000000000001 15123 2012-02-10T13:00:00.000 RAW 3.347 3.29 -0.05 0 0 0 118.5 1E-3 0.189 32.94 3.698 15123 2012-02-10T14:00:00.000 RAW 3.347 3.2519999999999998 -0.05 0 0 0 118.2 1E-3 0.252 11.07 0.23200000000000001 15123 2012-02-10T15:00:00.000 RAW 3.4039999999999999 2.9769999999999999 -0.05 0 0 0 118.5 0 0 0 0 15123 2012-02-10T16:00:00.000 RAW 3.5649999999999999 3.5369999999999999 -0.05 0 0 0 118.7 4.5999999999999999E-2 1.8240000000000001 21.25 3.82 15123 2012-02-10T17:00:00.000 RAW 3.5649999999999999 2.8439999999999999 -0.05 0 0 0 118.3 0.67100000000000004 5.7880000000000003 355.1 17.48 15123 2012-02-10T18:00:00.000 ST 3.5649999999999999 1.7270000000000001 -0.05 0 0 0 118.4 1.6970000000000001 9.6300000000000008 18.989999999999998 14.42 15123 2012-02-10T19:00:00.000 RAW 2.04 1.6519999999999999 1.425 0 0 0 118.2 3.734 11.58 18.190000000000001 12.04 15123 2012-02-10T20:00:00.000 RAW 2.04 0.52600000000000002 0.52600000000000002 0 0 0 118 7.49 15.04 31.79 16.78 15123 2012-02-10T21:00:00.000 RAW 2.04 0.47 0.13900000000000001 0 0 0 118 5.6929999999999996 14.54 25.93 21.47 15123 2012-02-10T22:00:00.000 RAW 2.04 0.92500000000000004 3.5999999999999997E-2 0 0 0 118 6.4160000000000004 15.99 20.9 20.57 15123 2012-02-10T23:00:00.000 RAW 2.04 0.57499999999999996 -0.21099999999999999 0 0 0 118.2 7.01 16.93 22.45 17.47 15123 2012-02-11T00:00:00.000 RAW 2.04 0.56499999999999995 -0.21099999999999999 0 0 0 118 2.6949999999999998 12.21 11.3 24.17 15123 2012-02-11T01:00:00.000 RAW 2.04 -0.219 -0.58899999999999997 0 0 0 118.3 3.0619999999999998 12.52 13 32.65 15123 2012-02-11T02:00:00.000 RAW 2.04 2.7E-2 -0.58899999999999997 0 0 0 118.2 3.1869999999999998 9.76 15.89 25.26 15123 2012-02-11T03:00:00.000 RAW 2.04 0.216 -0.58899999999999997 0 0 0 118.1 0.121 5.476 15.51 5.4180000000000001 15123 2012-02-11T04:00:00.000 RAW 2.04 0.254 -0.58899999999999997 0 0 0 118 0.76700000000000002 6.8609999999999998 15.6 14.65 15123 2012-02-11T05:00:00.000 RAW 2.04 2.5999999999999999E-2 -0.58899999999999997 0 0 0.1 118.3 1E-3 0.126 21.34 0.65600000000000003 15123 2012-02-11T06:00:00.000 ST 2.04 0.48099999999999998 -0.58899999999999997 0 0 0.1 118.2 0 0 0 0 15123 2012-02-11T07:00:00.000 RAW 0.65100000000000002 0.65100000000000002 0.48099999999999998 0 0 0 118.1 0 0 0 0 15123 2012-02-11T08:00:00.000 RAW 0.66 0.57499999999999996 0.48099999999999998 0 0 0 118 0 6.3E-2 122.8 0.26400000000000001 15123 2012-02-11T09:00:00.000 RAW 1.2649999999999999 1.246 0.48099999999999998 0 0 0 118 2.4E-2 2.3919999999999999 154 0.97499999999999998 15123 2012-02-11T10:00:00.000 RAW 1.974 1.964 0.48099999999999998 0 0 0 117.5 0 0.126 175.6 0 15123 2012-02-11T11:00:00.000 RAW 2.7879999999999998 2.7879999999999998 0.48099999999999998 0 0 0 117.4 0.34599999999999997 10.38 166 8.35 15123 2012-02-11T12:00:00.000 RAW 3.1579999999999999 3.0529999999999999 0.48099999999999998 0 0 0 117.2 1.403 11.01 164.9 23.27 15123 2012-02-11T13:00:00.000 RAW 4.9080000000000004 3.7930000000000001 0.48099999999999998 0 0 0 116.6 2.9609999999999999 12.58 158.30000000000001 23.7 15123 2012-02-11T14:00:00.000 RAW 4.9080000000000004 3.944 0.48099999999999998 0 0 0 116.6 5.57 13.84 151.19999999999999 23.73 15123 2012-02-11T15:00:00.000 RAW 4.9080000000000004 3.7829999999999999 0.48099999999999998 0 0 0 116.6 7.52 14.84 151.5 18.190000000000001 15123 2012-02-11T16:00:00.000 RAW 4.9080000000000004 3.109 0.48099999999999998 0 0 0 116.1 7.55 15.22 150.4 15.25 15123 2012-02-11T17:00:00.000 RAW 4.9080000000000004 2.266 0.48099999999999998 0 0 0 116.3 7.72 14.66 149.1 15.73 15123 2012-02-11T18:00:00.000 ST 4.9080000000000004 1.3959999999999999 0.48099999999999998 0 0 0 116.5 8.41 16.61 157.6 16.66 15123 2012-02-11T19:00:00.000 RAW 1.3959999999999999 1.113 1.103 0 0 0 116.3 10.45 18.440000000000001 144.5 15.87 15123 2012-02-11T20:00:00.000 RAW 1.3959999999999999 0.79100000000000004 0.79100000000000004 0 0 0 116.2 9.9600000000000009 16.170000000000002 147.30000000000001 14.57 15123 2012-02-11T21:00:00.000 RAW 1.3959999999999999 0.89600000000000002 0.68700000000000006 0 0 0 116.1 10.98 18.690000000000001 146.19999999999999 15.22 15123 2012-02-11T22:00:00.000 RAW 1.3959999999999999 0.55600000000000005 0.499 0 0 0 116.2 9.8699999999999992 20.079999999999998 146.4 14.35 15123 2012-02-11T23:00:00.000 RAW 1.3959999999999999 0.79200000000000004 0.499 0 0 0 116.1 8.83 16.239999999999998 139.6 13.13 15123 2012-02-12T00:00:00.000 RAW 1.3959999999999999 0.754 0.499 0 0 0 116 8.0399999999999991 16.43 141.4 13.33 15123 2012-02-12T01:00:00.000 RAW 1.3959999999999999 0.69699999999999995 0.499 0 0 0 116 7.65 17.239999999999998 150.4 13.2 15123 2012-02-12T02:00:00.000 RAW 1.3959999999999999 0.622 0.499 0 0 0 115.9 7.4 14.03 144.1 12.06 15123 2012-02-12T03:00:00.000 RAW 1.3959999999999999 0.50800000000000001 0.48899999999999999 0 0 0 115.8 7.88 15.92 141.5 13.58 15123 2012-02-12T04:00:00.000 RAW 1.3959999999999999 0.35699999999999998 0.35699999999999998 0 0 0 115.8 8.25 15.36 144.19999999999999 14.7 15123 2012-02-12T05:00:00.000 RAW 1.3959999999999999 0.16800000000000001 0.16800000000000001 0 0 0 115.9 8.0500000000000007 17.690000000000001 139.9 15.47 15123 2012-02-12T06:00:00.000 ST 1.3959999999999999 -0.23899999999999999 -0.25800000000000001 0 0 0 115.8 9.83 23.1 144.69999999999999 16.96 15123 2012-02-12T07:00:00.000 RAW -8.7999999999999995E-2 -0.16300000000000001 -0.23899999999999999 0 0 0 115.3 9.27 18.13 145.1 19.13 15123 2012-02-12T08:00:00.000 RAW -8.7999999999999995E-2 -0.14399999999999999 -0.23899999999999999 0 0 0 113.7 8.33 16.62 143.9 17.66 15123 2012-02-12T09:00:00.000 RAW -3.1E-2 -3.1E-2 -0.23899999999999999 0 0 0 112.3 7.49 18 143.69999999999999 17.100000000000001 15123 2012-02-12T10:00:00.000 RAW 0.17699999999999999 0.14899999999999999 -0.23899999999999999 0 0 0 114.1 7.48 14.35 140.80000000000001 17.670000000000002 15123 2012-02-12T11:00:00.000 RAW 0.42299999999999999 0.376 -0.23899999999999999 0 0 0 115.4 8.5399999999999991 19.95 142.5 18.73 15123 2012-02-12T12:00:00.000 RAW 0.45100000000000001 0.41299999999999998 -0.23899999999999999 0 0 0 115.8 9.3000000000000007 22.03 143.9 18.149999999999999 15123 2012-02-12T13:00:00.000 RAW 1.018 1.018 -0.23899999999999999 0 0 0 115.7 9.16 22.03 144.19999999999999 18.03 15123 2012-02-12T14:00:00.000 RAW 1.056 0.63 -0.23899999999999999 0 0 0 115.6 9.89 20.95 146 19.09 15123 2012-02-12T15:00:00.000 RAW 1.056 0.85699999999999998 -0.23899999999999999 0 0 0 115 7.93 16.739999999999998 149.9 18.739999999999998 15123 2012-02-12T16:00:00.000 RAW 1.056 0.53500000000000003 -0.23899999999999999 0 0 0 114.9 7.57 15.29 142.4 14.29 15123 2012-02-12T17:00:00.000 RAW 1.056 0.28000000000000003 -0.23899999999999999 0 0 0 114.4 6.4470000000000001 16.61 136.6 15.1 15123 2012-02-12T18:00:00.000 ST 1.056 7.0000000000000001E-3 -0.23899999999999999 0 0 0 114 7.11 16.11 145.6 16.97 15123 2012-02-12T19:00:00.000 RAW 3.5000000000000003E-2 -0.05 -5.8999999999999997E-2 0 0 0 113.9 5.15 12.52 143.69999999999999 17.18 15123 2012-02-12T20:00:00.000 RAW 3.5000000000000003E-2 -0.192 -0.192 0 0 0 113.9 4.1390000000000002 13.09 142.69999999999999 19.39 15123 2012-02-12T21:00:00.000 RAW 3.5000000000000003E-2 -0.29499999999999998 -0.314 0 0 0 113.9 1.9950000000000001 9.19 138.19999999999999 15.99 15123 2012-02-12T22:00:00.000 RAW 3.5000000000000003E-2 -0.4 -0.41799999999999998 0 0 0 113.9 1.393 7.62 144.69999999999999 12.83 15123 2012-02-12T23:00:00.000 RAW 3.5000000000000003E-2 -0.437 -0.45600000000000002 0 0 0 113.2 0.71799999999999997 6.1050000000000004 154.6 9.98 15123 2012-02-13T00:00:00.000 RAW 3.5000000000000003E-2 -0.44700000000000001 -0.45600000000000002 0 0 0 113.3 3.9E-2 2.3919999999999999 159.19999999999999 6.6449999999999996 15123 2012-02-13T01:00:00.000 RAW 3.5000000000000003E-2 -0.49399999999999999 -0.53200000000000003 0 0 0 113.2 5.0000000000000001E-3 0.69199999999999995 177 0.93 15123 2012-02-13T02:00:00.000 RAW 3.5000000000000003E-2 -0.54100000000000004 -0.54100000000000004 0 0 0.1 113.9 0 0 0 0 15123 2012-02-13T03:00:00.000 RAW 3.5000000000000003E-2 -0.79700000000000004 -1.024 0 0 1 114.2 0.216 3.5249999999999999 38.049999999999997 17.72 15123 2012-02-13T04:00:00.000 RAW 3.5000000000000003E-2 -0.873 -1.024 0 0 1 113.7 4.3899999999999997 14.04 16.059999999999999 27.52 15123 2012-02-13T05:00:00.000 RAW 3.5000000000000003E-2 -1.3839999999999999 -1.3839999999999999 0 0 1 113 5.2839999999999998 12.97 29.66 21.8 15123 2012-02-13T06:00:00.000 ST 3.5000000000000003E-2 -1.4970000000000001 -1.4970000000000001 0 0 1 112.6 4.8760000000000003 13.47 28.53 22.72 15123 2012-02-13T07:00:00.000 RAW -1.4590000000000001 -1.611 -1.611 0 0 0 112.6 4.5259999999999998 13.72 22.97 21.57 15123 2012-02-13T08:00:00.000 RAW -1.4590000000000001 -1.6479999999999999 -1.696 0 0 0.1 113 3.9359999999999999 11.2 18.239999999999998 24.69 15123 2012-02-13T09:00:00.000 RAW -1.45 -1.478 -1.696 0 0 1 113.6 3.016 10.14 18.84 23.86 15123 2012-02-13T10:00:00.000 RAW -1.421 -1.952 -1.952 0 0 2 113.9 5.601 13.91 13.21 25.81 15123 2012-02-13T11:00:00.000 RAW -1.27 -1.27 -1.952 0 0 2 114.1 8.74 22.41 33.119999999999997 24.55 15123 2012-02-13T12:00:00.000 RAW 1.492 1.492 -1.952 0 0 2 113.6 5.8470000000000004 21.15 37.619999999999997 25.8 15123 2012-02-13T13:00:00.000 RAW 3.1930000000000001 2.6890000000000001 -1.952 0 0 2 113.6 2.4809999999999999 14.22 2.427 28.47 15123 2012-02-13T14:00:00.000 RAW 3.3140000000000001 3.3140000000000001 -1.952 0 0 2 114.1 2.448 12.57 331.1 25.15 15123 2012-02-13T15:00:00.000 RAW 3.3610000000000002 1.95 -1.952 0 0 3 114.7 1.0629999999999999 8.5500000000000007 291.3 16.72 15123 2012-02-13T16:00:00.000 RAW 4.5330000000000004 4.3140000000000001 -1.952 0 0 3 113.7 0.38600000000000001 5.5960000000000001 263.89999999999998 7.84 15123 2012-02-13T17:00:00.000 RAW 4.5330000000000004 0.42899999999999999 -1.952 0 0 3 115.1 1.9E-2 0.94299999999999995 280.89999999999998 1.506 15123 2012-02-13T18:00:00.000 ST 4.5330000000000004 -1.2150000000000001 -1.952 0 0 4 115.3 8.1000000000000003E-2 2.7679999999999998 18.93 2.9319999999999999 15123 2012-02-13T19:00:00.000 RAW -1.2150000000000001 -2.133 -2.133 0 0 1 115.8 5.2999999999999999E-2 1.9510000000000001 29.74 5.5780000000000003 15123 2012-02-13T20:00:00.000 RAW -1.2150000000000001 -3.0449999999999999 -3.0449999999999999 0 0 1 115.5 4.2000000000000003E-2 1.7629999999999999 170.1 2.4 15123 2012-02-13T21:00:00.000 RAW -1.2150000000000001 -2.835 -3.0539999999999998 0 0 1 114.8 9.1999999999999998E-2 1.952 154.5 4.32 15123 2012-02-13T22:00:00.000 RAW -1.2150000000000001 -2.2450000000000001 -3.177 0 0 1 114.7 0.23599999999999999 5.1630000000000003 159 10.06 15123 2012-02-13T23:00:00.000 RAW -1.2150000000000001 -2.7109999999999999 -3.177 0 0 1 114.9 2.5000000000000001E-2 1.448 158.19999999999999 4.7489999999999997 15123 2012-02-14T00:00:00.000 RAW -1.2150000000000001 -2.4929999999999999 -3.177 0 0 1 114.9 1.0999999999999999E-2 1.196 187.2 1.6659999999999999 15123 2012-02-14T01:00:00.000 RAW -1.2150000000000001 -2.2930000000000001 -3.177 0 0 1 114.7 0 6.3E-2 194.5 3.0000000000000001E-3 15123 2012-02-14T02:00:00.000 RAW -1.2150000000000001 -2.6160000000000001 -3.177 0 0 1 114.9 1.9E-2 2.0150000000000001 166 1.19 15123 2012-02-14T03:00:00.000 RAW -1.2150000000000001 -2.3879999999999999 -3.177 0 0 1 114.8 2.2890000000000001 11.14 149.4 15.7 15123 2012-02-14T04:00:00.000 RAW -1.2150000000000001 -2.4929999999999999 -3.177 0 0 1 114.7 4.2640000000000002 13.41 154.5 20.36 15123 2012-02-14T05:00:00.000 RAW -1.2150000000000001 -2.36 -3.177 0 0 1 114.6 3.1640000000000001 13.79 162.1 20.260000000000002 15123 2012-02-14T06:00:00.000 ST -1.2150000000000001 -2.3130000000000002 -3.177 0 0 1 114.9 2.2599999999999998 11.4 161.9 19.52 15123 2012-02-14T07:00:00.000 RAW -2.274 -2.8260000000000001 -2.835 0 0 0 114.6 0.153 2.5179999999999998 160.69999999999999 9.74 15123 2012-02-14T08:00:00.000 RAW -2.274 -3.4350000000000001 -3.4350000000000001 0 0 0 114.7 2E-3 0.315 79.5 3.839 15123 2012-02-14T09:00:00.000 RAW -2.274 -4.2279999999999998 -4.3630000000000004 0 0 0 114.6 1.5109999999999999 8.94 24.37 11.63 15123 2012-02-14T10:00:00.000 RAW -2.274 -4.1429999999999998 -4.3630000000000004 0 0 0 114.6 5.3479999999999999 15.49 29.73 23.22 15123 2012-02-14T11:00:00.000 RAW -2.274 -2.484 -4.3630000000000004 0 0 0 114.5 6.3010000000000002 16.309999999999999 21.5 25.62 15123 2012-02-14T12:00:00.000 RAW -1.849 -2.048 -4.3630000000000004 0 0 0 114.7 2.4380000000000002 9.57 22.9 23.88 15123 2012-02-14T13:00:00.000 RAW 0.17499999999999999 8.8999999999999996E-2 -4.3630000000000004 0 0 0 114.4 4.4589999999999996 13.72 17.100000000000001 29.86 15123 2012-02-14T14:00:00.000 RAW 1.952 1.952 -4.3630000000000004 0 0 0.1 114.7 5.4269999999999996 14.03 6.867 27.82 15123 2012-02-14T15:00:00.000 RAW 2.16 0.45700000000000002 -4.3630000000000004 0 0 1 115 3.9630000000000001 13.77 343 29.78 15123 2012-02-14T16:00:00.000 RAW 3.0230000000000001 3.0230000000000001 -4.3630000000000004 0 0 1 113.9 0.245 3.145 294.3 12.68 15123 2012-02-14T17:00:00.000 RAW 3.109 -1.3109999999999999 -4.3630000000000004 0 0 1 115.4 0.106 3.9630000000000001 264 2.887 15123 2012-02-14T18:00:00.000 ST 3.109 -3.3220000000000001 -4.3630000000000004 0 0 2 115.9 7.0000000000000001E-3 1.3839999999999999 16.5 4.8710000000000004 15123 2012-02-14T19:00:00.000 RAW -3.2069999999999999 -3.9510000000000001 -3.9510000000000001 0 0 0 116.1 1E-3 0.252 21.17 3.2450000000000001 15123 2012-02-14T20:00:00.000 RAW -3.2069999999999999 -4.2569999999999997 -4.2569999999999997 0 0 0 115.8 0 0 0 0 15123 2012-02-14T21:00:00.000 RAW -3.2069999999999999 -3.9590000000000001 -4.3520000000000003 0 0 0 115.7 0 0 0 0 15123 2012-02-14T22:00:00.000 RAW -3.2069999999999999 -4.4089999999999998 -4.5919999999999996 0 0 0 115.6 5.5E-2 2.5190000000000001 165.6 0.89200000000000002 15123 2012-02-14T23:00:00.000 RAW -3.2069999999999999 -3.6440000000000001 -4.5919999999999996 0 0 0 115.2 0.17100000000000001 2.96 170.9 4.3630000000000004 15123 2012-02-15T00:00:00.000 RAW -3.2069999999999999 -3.31 -4.5919999999999996 0 0 0 115.3 0 0 0 0 15123 2012-02-15T01:00:00.000 RAW -3.206 -3.54 -4.5919999999999996 0 0 0 115.3 1E-3 0.126 107.6 3.5999999999999997E-2 15123 2012-02-15T02:00:00.000 RAW -2.7970000000000002 -2.806 -4.5919999999999996 0 0 0 115.1 0 0.189 261.3 0 15123 2012-02-15T03:00:00.000 RAW -2.7970000000000002 -3.1389999999999998 -4.5919999999999996 0 0 0 114.8 1E-3 0.189 36.130000000000003 1.853 15123 2012-02-15T04:00:00.000 RAW -2.7970000000000002 -3.1869999999999998 -4.5919999999999996 0 0 0 114.9 0 6.3E-2 15.91 0.44800000000000001 15123 2012-02-15T05:00:00.000 RAW -2.7970000000000002 -3.0819999999999999 -4.5919999999999996 0 0 0 115.1 0.11 3.2109999999999999 341.3 1.0920000000000001 15123 2012-02-15T06:00:00.000 ST -2.7970000000000002 -2.9489999999999998 -4.5919999999999996 0 0 0 114.9 0 0 0 0 15123 2012-02-15T07:00:00.000 RAW -2.911 -2.92 -3.016 0 0 0 114.7 0 0.126 182.7 7.4999999999999997E-2 15123 2012-02-15T08:00:00.000 RAW -2.6829999999999998 -2.6920000000000002 -3.016 0 0 0 114.6 0.55400000000000005 6.7359999999999998 169.3 11.87 15123 2012-02-15T09:00:00.000 RAW -2.54 -2.54 -3.016 0 0 0 114.5 1.8360000000000001 8.25 153.6 15.49 15123 2012-02-15T10:00:00.000 RAW -1.08 -1.08 -3.016 0 0 0 114.4 0.52500000000000002 8.5 172.4 12.87 15123 2012-02-15T11:00:00.000 RAW -0.36199999999999999 -0.36199999999999999 -3.016 0 0 0 114.3 1.8879999999999999 10.14 170.8 19.559999999999999 15123 2012-02-15T12:00:00.000 RAW 1.6E-2 -0.06 -3.016 0 0 0 114.3 2.391 13.47 152.80000000000001 26.61 15123 2012-02-15T13:00:00.000 RAW 5.2999999999999999E-2 -4.2000000000000003E-2 -3.016 0 0 0 114.4 3.8210000000000002 13.59 150.9 20.09 15123 2012-02-15T14:00:00.000 RAW 0.29899999999999999 3.4000000000000002E-2 -3.016 0 0 0 114.5 4.2910000000000004 12.96 147.6 18.91 15123 2012-02-15T15:00:00.000 RAW 0.29899999999999999 0.29899999999999999 -3.016 0 0 0 114.2 2.91 9 153.4 16.32 15123 2012-02-15T16:00:00.000 RAW 0.43099999999999999 0.28899999999999998 -3.016 0 0 0 114.1 2.8839999999999999 9.31 150.19999999999999 16.010000000000002 15123 2012-02-15T17:00:00.000 RAW 0.43099999999999999 -1.395 -3.016 0 0 0.1 114.7 2.1629999999999998 9.31 148 20.36 15123 2012-02-15T18:00:00.000 ST 0.43099999999999999 -1.925 -3.016 0 0 1 115 2.1160000000000001 9.19 151.80000000000001 16.489999999999998 15123 2012-02-15T19:00:00.000 RAW -1.8680000000000001 -2.2749999999999999 -2.56 0 0 0 114.9 2.484 12.72 194.9 17.14 15123 2012-02-15T20:00:00.000 RAW -1.724 -1.7909999999999999 -2.56 0 0 0 114.5 3.0859999999999999 12.47 156.19999999999999 18.14 15123 2012-02-15T21:00:00.000 RAW -1.724 -1.923 -2.56 0 0 0 114.5 4.2709999999999999 12.72 151.1 13.94 15123 2012-02-15T22:00:00.000 RAW -1.724 -2.0939999999999999 -2.56 0 0 0 114.4 4.8959999999999999 12.59 145.4 14.9 15123 2012-02-15T23:00:00.000 RAW -1.724 -2.36 -2.56 0 0 0 114.4 6.6790000000000003 16.309999999999999 146.5 17.39 15123 2012-02-16T00:00:00.000 RAW -1.724 -2.5019999999999998 -2.56 0 0 0 114.4 6.3310000000000004 15.55 151 18.23 15123 2012-02-16T01:00:00.000 RAW -1.724 -2.6160000000000001 -2.6539999999999999 0 0 0 114.3 7.84 18.38 148.69999999999999 17.61 15123 2012-02-16T02:00:00.000 RAW -1.724 -2.4359999999999999 -2.6539999999999999 0 0 0 114.2 6.9480000000000004 14.29 148.1 15.52 15123 2012-02-16T03:00:00.000 RAW -1.724 -2.1789999999999998 -2.6539999999999999 0 0 0 114.3 6.0679999999999996 16.62 138.1 17.07 15123 2012-02-16T04:00:00.000 RAW -1.724 -2.246 -2.6539999999999999 0 0 0 114.3 7.69 21.03 137.9 19.559999999999999 15123 2012-02-16T05:00:00.000 RAW -1.724 -2.6829999999999998 -2.6930000000000001 0 0 0 113.4 7.62 16.489999999999998 146.1 19.29 15123 2012-02-16T06:00:00.000 ST -1.724 -2.5019999999999998 -2.7120000000000002 0 0 0.1 114.7 6.34 15.55 132.80000000000001 16.579999999999998 15123 2012-02-16T07:00:00.000 RAW -2.492 -2.5880000000000001 -2.6640000000000001 0 0 0 113.3 4.1680000000000001 12.72 140.9 16.47 15123 2012-02-16T08:00:00.000 RAW -2.407 -2.4169999999999998 -2.6640000000000001 0 0 0 114.3 1.3680000000000001 5.0999999999999996 151.4 11.67 15123 2012-02-16T09:00:00.000 RAW -1.7430000000000001 -1.7430000000000001 -2.6640000000000001 0 0 0 113.1 2.0739999999999998 7.43 151 14.26 15123 2012-02-16T10:00:00.000 RAW -0.67300000000000004 -0.70199999999999996 -2.6640000000000001 0 0 0 113.9 1.6639999999999999 8.18 166.2 14.67 15123 2012-02-16T11:00:00.000 RAW -0.154 -0.154 -2.6640000000000001 0 0 0 112 0.58699999999999997 8.3699999999999992 152.4 11.14 15123 2012-02-16T12:00:00.000 RAW 0.84799999999999998 0.82 -2.6640000000000001 0 0 0 111.2 2.1869999999999998 12.97 156.19999999999999 16.77 15123 2012-02-16T13:00:00.000 RAW 1.0369999999999999 0.28000000000000003 -2.6640000000000001 0 0 0 107 3.4260000000000002 11.83 150.30000000000001 15.26 15123 2012-02-16T14:00:00.000 RAW 1.3480000000000001 1.31 -2.6640000000000001 0 0 0 114.6 2.5150000000000001 11.26 151.5 13.41 15123 2012-02-16T15:00:00.000 RAW 1.4710000000000001 1.4419999999999999 -2.6640000000000001 0 0 0 113.9 5.1859999999999999 14.28 165.8 17.79 15123 2012-02-16T16:00:00.000 RAW 2.7010000000000001 2.1040000000000001 -2.6640000000000001 0 0 0 113.2 5.8410000000000002 16.989999999999998 159.9 17.3 15123 2012-02-16T17:00:00.000 RAW 2.7010000000000001 -0.98 -2.6640000000000001 0 0 1 114.8 6.6749999999999998 17.93 153.30000000000001 16.91 15123 2012-02-16T18:00:00.000 ST 2.7010000000000001 -1.6120000000000001 -2.6640000000000001 0 0 1 114.8 7.16 17.37 151 16.010000000000002 15123 2012-02-16T19:00:00.000 RAW -1.546 -2.2650000000000001 -2.2650000000000001 0 0 0 114.3 3.6970000000000001 14.48 153 14 15123 2012-02-16T20:00:00.000 RAW -1.546 -1.857 -2.294 0 0 0 114.2 1.0780000000000001 5.35 153.4 2.7890000000000001 15123 2012-02-16T21:00:00.000 RAW -1.4019999999999999 -1.5349999999999999 -2.294 0 0 0 114.1 0.22900000000000001 3.3370000000000002 148.80000000000001 2.5990000000000002 15123 2012-02-16T22:00:00.000 RAW -1.4019999999999999 -1.5349999999999999 -2.294 0 0 0 113.7 0 0.126 73.400000000000006 5.0000000000000001E-3 15123 2012-02-16T23:00:00.000 RAW -1.3640000000000001 -1.421 -2.294 0 0 0 113.4 2.7E-2 2.4550000000000001 32.18 2.44 15123 2012-02-17T00:00:00.000 RAW -1.355 -1.667 -2.294 0 0 0 113.6 0.82199999999999995 6.2960000000000003 21.77 14.23 15123 2012-02-17T01:00:00.000 RAW -1.355 -1.7150000000000001 -2.294 0 0 0 112.6 1.048 6.4850000000000003 22.46 9.67 15123 2012-02-17T02:00:00.000 RAW -1.355 -1.857 -2.294 0 0 0 111.9 2.0609999999999999 7.37 35.590000000000003 12.88 15123 2012-02-17T03:00:00.000 RAW -1.355 -1.9139999999999999 -2.294 0 0 0 111.1 0.55600000000000005 6.548 24.76 3.0739999999999998 15123 2012-02-17T04:00:00.000 RAW -1.355 -2.0470000000000002 -2.294 0 0 0 110.6 0.125 2.0779999999999998 19.170000000000002 5.9829999999999997 15123 2012-02-17T05:00:00.000 RAW -1.355 -2.141 -2.294 0 0 0 110.5 5.0000000000000001E-3 0.56699999999999995 26.53 6.7969999999999997 15123 2012-02-17T06:00:00.000 ST -1.355 -2.2549999999999999 -2.379 0 0 0 110.3 0 0 0 0 15123 2012-02-17T07:00:00.000 RAW -2.1789999999999998 -2.407 -2.407 0 0 0 109.9 0.03 1.889 24.79 2.093 15123 2012-02-17T08:00:00.000 RAW -2.1789999999999998 -2.617 -2.8260000000000001 0 0 0 109.9 1.399 6.2960000000000003 49.79 18.670000000000002 15123 2012-02-17T09:00:00.000 RAW -1.762 -1.762 -2.8260000000000001 0 0 0 109.9 0.55000000000000004 4.5960000000000001 16.09 25.38 15123 2012-02-17T10:00:00.000 RAW -0.626 -0.69299999999999995 -2.8260000000000001 0 0 0 110.1 3.7999999999999999E-2 1.448 15.92 2.3969999999999998 15123 2012-02-17T11:00:00.000 RAW -0.626 -0.71299999999999997 -2.8260000000000001 0 0 0.1 110.5 0.16800000000000001 2.077 12.39 11.23 15123 2012-02-17T12:00:00.000 RAW 2.1059999999999999 1.841 -2.8260000000000001 0 0 4 113.9 0.01 0.94399999999999995 275.8 3.851 15123 2012-02-17T13:00:00.000 RAW 3.8780000000000001 2.9089999999999998 -2.8260000000000001 0 0 5 114.2 2.3E-2 2.2650000000000001 278.7 2.61 15123 2012-02-17T14:00:00.000 RAW 4.1520000000000001 3.7229999999999999 -2.8260000000000001 0 0 5 114.2 1E-3 0.126 289.5 0.63800000000000001 15123 2012-02-17T15:00:00.000 RAW 4.1520000000000001 4.1040000000000001 -2.8260000000000001 0 0 5 114.5 0 0 0 0 15123 2012-02-17T16:00:00.000 RAW 4.2750000000000004 3.2589999999999999 -2.8260000000000001 0 0 6 115 0 0.126 239.7 3.1819999999999999 15123 2012-02-17T17:00:00.000 RAW 4.2750000000000004 2.5390000000000001 -2.8260000000000001 0 0 6 114.6 0.92100000000000004 15.66 99.3 15.33 15123 2012-02-17T18:00:00.000 ST 4.2750000000000004 5.1999999999999998E-2 -2.8260000000000001 0 0 7 115.9 1.0049999999999999 8.99 141.1 23.87 15123 2012-02-17T19:00:00.000 RAW 5.1999999999999998E-2 -0.24 -0.24 0 0 0 111.7 1.0429999999999999 7.55 133 13.87 15123 2012-02-17T20:00:00.000 RAW 5.1999999999999998E-2 -0.27700000000000002 -0.29599999999999999 0 0 0 114.7 0.33200000000000002 5.2229999999999999 121.6 15.41 15123 2012-02-17T21:00:00.000 RAW 5.1999999999999998E-2 -0.55100000000000005 -0.57899999999999996 0 0 2 117.7 5.016 15.36 142.5 20.84 15123 2012-02-17T22:00:00.000 RAW 5.1999999999999998E-2 -1.3080000000000001 -1.3080000000000001 0 0 6.1559999999999997 21.59 139.80000000000001 23.08 15123 2012-02-17T23:00:00.000 RAW 5.1999999999999998E-2 -1.44 -1.45 0 0 3 113.8 5.5570000000000004 16.739999999999998 141 20.07 15123 2012-02-18T00:00:00.000 RAW 5.1999999999999998E-2 -1.46 -1.554 0 0 4.1399999999999997 15.11 144.9 16.62 15123 2012-02-18T01:00:00.000 RAW 5.1999999999999998E-2 -1.4019999999999999 -1.5920000000000001 0 0 1.302 8.6199999999999992 148.6 19.23 15123 2012-02-18T02:00:00.000 RAW 5.1999999999999998E-2 -1.5820000000000001 -1.5920000000000001 0 0 3 116.9 1.6619999999999999 9.9499999999999993 157 16.95 15123 2012-02-18T03:00:00.000 RAW 5.1999999999999998E-2 -1.5920000000000001 -1.6579999999999999 0 0 3 116.1 2.3660000000000001 11.2 147.30000000000001 17.13 15123 2012-02-18T04:00:00.000 RAW 5.1999999999999998E-2 -1.696 -1.696 0 0 8 122.7 2.2069999999999999 11.71 144 18.78 15123 2012-02-18T05:00:00.000 RAW 5.1999999999999998E-2 -1.696 -1.706 0 0 8 118.2 1.75 8.5 146 20.14 15123 2012-02-18T06:00:00.000 ST 5.1999999999999998E-2 -1.7909999999999999 -1.8009999999999999 0 0 8 114.7 2.97 10.01 147.80000000000001 22.31 15123 2012-02-18T07:00:00.000 RAW -1.7150000000000001 -1.744 -1.8 0 0 8 122.2 2.25 9.19 146.69999999999999 16.29 15123 2012-02-18T08:00:00.000 RAW -1.7050000000000001 -1.706 -1.8 0 0 8 120.7 2.1179999999999999 9.32 150.69999999999999 19.22 15123 2012-02-18T09:00:00.000 RAW -1.3640000000000001 -1.3640000000000001 -1.8 0 0 10 123.8 2.2309999999999999 9.44 154.19999999999999 18.18 15123 2012-02-18T10:00:00.000 RAW -0.57899999999999996 -0.58899999999999997 -1.8 0 0 10 124 1.64 9.51 151.1 17.989999999999998 15123 2012-02-18T11:00:00.000 RAW -0.107 -0.154 -1.8 0 0 10 120.8 1.716 9.82 149.9 21.08 15123 2012-02-18T12:00:00.000 RAW 7.0000000000000001E-3 -0.221 -1.8 0 0 11 123.9 3.1120000000000001 10.199999999999999 150.4 17.34 15123 2012-02-18T13:00:00.000 RAW 0.252 8.1000000000000003E-2 -1.8 0 0 11 123.2 2.016 11.14 149 9.6 15123 2012-02-18T14:00:00.000 RAW 0.77200000000000002 0.157 -1.8 0 0 11 121.5 2E-3 0.252 170.6 0.66500000000000004 15123 2012-02-18T15:00:00.000 RAW 0.77200000000000002 -4.0000000000000001E-3 -1.8 0 0 11 123.6 1E-3 0.252 174.6 3.5259999999999998 15123 2012-02-18T16:00:00.000 RAW 0.77200000000000002 0.129 -1.8 0 0 4.9000000000000002E-2 2.391 183.8 2.6179999999999999 15123 2012-02-18T17:00:00.000 RAW 0.77200000000000002 -1.2150000000000001 -1.8 0 0 11 122.2 0.57299999999999995 5.6630000000000003 164.9 9.4700000000000006 15123 2012-02-18T18:00:00.000 ST 0.77200000000000002 -1.6020000000000001 -1.8 0 0 11 122.3 1.663 11.01 148.9 6.9710000000000001 15123 2012-02-18T19:00:00.000 RAW -1.5449999999999999 -1.6579999999999999 -1.839 0 0 1 122.9 6.4189999999999996 12.78 144.69999999999999 12.04 15123 2012-02-18T20:00:00.000 RAW -1.4970000000000001 -1.5920000000000001 -1.839 0 0 1 122.8 4.4930000000000003 16.11 145.80000000000001 16.5 15123 2012-02-18T21:00:00.000 RAW -1.4970000000000001 -1.706 -1.839 0 0 1 122.8 5.4269999999999996 23.54 150.1 19.29 15123 2012-02-18T22:00:00.000 RAW -1.4970000000000001 -1.724 -1.867 0 0 1 122.9 7.4 17.25 140.5 17.440000000000001 15123 2012-02-18T23:00:00.000 RAW -1.4970000000000001 -1.857 -1.867 0 0 3 124.4 8.06 20.46 148.6 19.809999999999999 15123 2012-02-19T00:00:00.000 RAW -1.4970000000000001 -2.056 -2.0659999999999998 0 0 4 124.5 5.5449999999999999 15.8 133.5 18.8 15123 2012-02-19T01:00:00.000 RAW -1.4970000000000001 -2.246 -2.246 0 0 4 124.5 7.49 21.09 138.69999999999999 16.89 15123 2012-02-19T02:00:00.000 RAW -1.4970000000000001 -2.1320000000000001 -2.246 0 0 4 124.5 6.5389999999999997 20.399999999999999 148.1 20.010000000000002 15123 2012-02-19T03:00:00.000 RAW -1.4970000000000001 -2.2269999999999999 -2.246 0 0 4 124.4 7.3 18.89 146.4 18.32 15123 2012-02-19T04:00:00.000 RAW -1.4970000000000001 -2.3319999999999999 -2.36 0 0 4 124.3 7.42 19.079999999999998 141.80000000000001 20.74 15123 2012-02-19T05:00:00.000 RAW -1.4970000000000001 -2.4929999999999999 -2.5209999999999999 0 0 5 124.4 8.1999999999999993 19.829999999999998 147.9 22.11 15123 2012-02-19T06:00:00.000 ST -1.4970000000000001 -2.6539999999999999 -2.6930000000000001 0 0 5 124.4 9.41 31.04 149.80000000000001 23.03 15123 2012-02-19T07:00:00.000 RAW -2.6539999999999999 -2.778 -2.778 0 0 0 123.9 6.1890000000000001 18.7 144.69999999999999 22.73 15123 2012-02-19T08:00:00.000 RAW -2.6539999999999999 -2.8540000000000001 -3.0070000000000001 0 0 1 124.8 4.9820000000000002 22.92 150.30000000000001 20.260000000000002 15123 2012-02-19T09:00:00.000 RAW -2.4550000000000001 -2.5019999999999998 -3.0070000000000001 0 0 1 124.8 4.0380000000000003 14.67 137.9 19.18 15123 2012-02-19T10:00:00.000 RAW -2.2170000000000001 -2.5310000000000001 -3.0070000000000001 0 0 1 123.6 5.6890000000000001 20.96 146 19.739999999999998 15123 2012-02-19T11:00:00.000 RAW -2.2170000000000001 -2.6070000000000002 -3.0070000000000001 0 0 2 125.5 7.3 19.96 148.5 20.9 15123 2012-02-19T12:00:00.000 RAW -2.2170000000000001 -2.266 -3.0070000000000001 0 0 2 124.5 9.5 21.53 148.19999999999999 20.78 15123 2012-02-19T13:00:00.000 RAW -1.9350000000000001 -2.0099999999999998 -3.0070000000000001 0 0 2 125.3 9.4700000000000006 21.53 146.69999999999999 25.12 15123 2012-02-19T14:00:00.000 RAW -1.9350000000000001 -2.3239999999999998 -3.0070000000000001 0 0 4 127.2 8.06 26.75 145.30000000000001 26.76 15123 2012-02-19T15:00:00.000 RAW -1.9350000000000001 -2.59 -3.0070000000000001 0 0 4 126.7 7.29 20.77 142.5 26.15 15123 2012-02-19T16:00:00.000 RAW -1.9350000000000001 -2.8650000000000002 -3.0070000000000001 0 0 4 122.5 7.1 19.95 142.5 25.67 15123 2012-02-19T17:00:00.000 RAW -1.9350000000000001 -3.3410000000000002 -3.3410000000000002 0 0 4 123.8 5.0149999999999997 15.3 142.6 22.5 15123 2012-02-19T18:00:00.000 ST -1.9350000000000001 -3.617 -3.6269999999999998 0 0 6 128.4 7.13 19.71 143 21.26 15123 2012-02-19T19:00:00.000 RAW -3.6070000000000002 -3.6829999999999998 -3.702 0 0 0 127.9 6.3639999999999999 18.13 136.19999999999999 19.95 15123 2012-02-19T20:00:00.000 RAW -3.6070000000000002 -4.0750000000000002 -4.0750000000000002 0 0 0 127.9 7.6 16.43 150.19999999999999 18.91 15123 2012-02-19T21:00:00.000 RAW -3.6070000000000002 -4.0270000000000001 -4.1040000000000001 0 0 0 127.8 6.8630000000000004 18.38 153.1 15.92 15123 2012-02-19T22:00:00.000 RAW -3.6070000000000002 -4.0940000000000003 -4.1040000000000001 0 0 0 127.8 3.5979999999999999 13.79 146.9 16.170000000000002 15123 2012-02-19T23:00:00.000 RAW -3.6070000000000002 -4.056 -4.1040000000000001 0 0 0 127.6 6.3940000000000001 13.35 148.19999999999999 16.829999999999998 15123 2012-02-20T00:00:00.000 RAW -3.6070000000000002 -4.41 -4.41 0 0 0 127.7 4.9039999999999999 16.559999999999999 155.9 12.37 15123 2012-02-20T01:00:00.000 RAW -3.6070000000000002 -4.3040000000000003 -4.41 0 0 1 128 2.7719999999999998 12.78 157.9 12.69 15123 2012-02-20T02:00:00.000 RAW -3.6070000000000002 -4.3049999999999997 -4.42 0 0 1 127.8 3.2000000000000001E-2 1.385 162.4 2.9540000000000002 15123 2012-02-20T03:00:00.000 RAW -3.6070000000000002 -4.1609999999999996 -4.42 0 0 1 128.5 0.436 4.03 152.4 11.25 15123 2012-02-20T04:00:00.000 RAW -3.6070000000000002 -4.1989999999999998 -4.42 0 0 2 128.69999999999999 0.499 3.9039999999999999 164.3 13.6 15123 2012-02-20T05:00:00.000 RAW -3.6070000000000002 -4.218 -4.42 0 0 2 129.1 0.61899999999999999 5.9820000000000002 163.9 14.77 15123 2012-02-20T06:00:00.000 ST -3.6070000000000002 -4.3049999999999997 -4.42 0 0 3 129.30000000000001 0.30399999999999999 3.9039999999999999 161.9 11.56 15123 2012-02-20T07:00:00.000 RAW -4.2949999999999999 -4.4489999999999998 -4.4489999999999998 0 0 0 129.1 0.13100000000000001 2.8969999999999998 159.30000000000001 11.47 15123 2012-02-20T08:00:00.000 RAW -4.2949999999999999 -4.7649999999999997 -5.0060000000000002 0 0 0 128.9 5.5E-2 2.5819999999999999 161.80000000000001 5.3410000000000002 15123 2012-02-20T09:00:00.000 RAW -4.2190000000000003 -4.2279999999999998 -5.0439999999999996 0 0 0 128.69999999999999 0 0 0 0 15123 2012-02-20T10:00:00.000 RAW -1.7609999999999999 -1.8660000000000001 -5.0439999999999996 0 0 0 128.30000000000001 0 0 0 0 15123 2012-02-20T11:00:00.000 RAW -0.86399999999999999 -0.86399999999999999 -5.0439999999999996 0 0 0 128.19999999999999 0 0.126 256.60000000000002 2E-3 15123 2012-02-20T12:00:00.000 RAW 0.8 0.128 -5.0439999999999996 0 0 0 128.4 1.266 10.01 167.9 16.53 15123 2012-02-20T13:00:00.000 RAW 0.8 0.504 -5.0439999999999996 0 0 0 127.9 5.52 15.04 144.80000000000001 21.43 15123 2012-02-20T14:00:00.000 RAW 0.8 -1.4259999999999999 -5.0439999999999996 0 0 0 128.1 6.95 18.05 139 22.52 15123 2012-02-20T15:00:00.000 RAW 0.8 -1.415 -5.0439999999999996 0 0 0 125.2 5.5140000000000002 16.04 136.9 18.670000000000002 15123 2012-02-20T16:00:00.000 RAW 0.8 -1.641 -5.0439999999999996 0 0 0 126.8 8.23 17.62 136.9 18.73 15123 2012-02-20T17:00:00.000 RAW 0.8 -1.8109999999999999 -5.0439999999999996 0 0 0 127.4 9.23 18.760000000000002 137.69999999999999 17.22 15123 2012-02-20T18:00:00.000 ST 0.8 -2.0569999999999999 -5.0439999999999996 0 0 1 128.6 10.56 22.22 141.80000000000001 19.84 15123 2012-02-20T19:00:00.000 RAW -1.877 -1.877 -2.0859999999999999 0 0 0 128.69999999999999 9.8800000000000008 22.03 139.1 15.78 15123 2012-02-20T20:00:00.000 RAW -1.629 -1.724 -2.0859999999999999 0 0 0 128.69999999999999 7.15 17.059999999999999 136.9 14.02 15123 2012-02-20T21:00:00.000 RAW -1.629 -1.677 -2.0859999999999999 0 0 0 128.6 10.95 22.16 139.4 16.559999999999999 15123 2012-02-20T22:00:00.000 RAW -1.411 -1.411 -2.0859999999999999 0 0 0 128.4 11.02 23.23 136.6 16.07 15123 2012-02-20T23:00:00.000 RAW -1.3640000000000001 -1.4019999999999999 -2.0859999999999999 0 0 0 126.6 9.75 22.79 141.5 19.260000000000002 15123 2012-02-21T00:00:00.000 RAW -1.327 -1.3360000000000001 -2.0859999999999999 0 0 0 128.30000000000001 10.3 22.66 151 21.57 15123 2012-02-21T01:00:00.000 RAW -1.1180000000000001 -1.1279999999999999 -2.0859999999999999 0 0 0 121.2 11.68 25.94 147.1 21.36 15123 2012-02-21T02:00:00.000 RAW -1.042 -1.042 -2.0859999999999999 0 0 0 127.4 13.43 35.19 146.80000000000001 21.91 15123 2012-02-21T03:00:00.000 RAW -0.67300000000000004 -0.67300000000000004 -2.0859999999999999 0 0 0 127.3 11.26 24.99 140.30000000000001 20.059999999999999 15123 2012-02-21T04:00:00.000 RAW -0.38900000000000001 -0.38900000000000001 -2.0859999999999999 0 0 0 127.1 9.1199999999999992 20.84 138.1 18 15123 2012-02-21T05:00:00.000 RAW -0.35199999999999998 -0.39900000000000002 -2.0859999999999999 0 0 0 127.1 11.2 23.48 139.69999999999999 19.57 15123 2012-02-21T06:00:00.000 ST -0.27600000000000002 -0.30399999999999999 -2.0859999999999999 0 0 0 127.2 12.78 25.43 140 19.79 15123 2012-02-21T07:00:00.000 RAW -0.17199999999999999 -0.23799999999999999 -0.30399999999999999 0 0 0 126.9 11.98 25.18 139.4 17.34 15123 2012-02-21T08:00:00.000 RAW -0.17199999999999999 -0.17199999999999999 -0.30499999999999999 0 0 1 127.8 9.1 20.39 133.80000000000001 20.83 15123 2012-02-21T09:00:00.000 RAW 0.111 0.111 -0.30499999999999999 0 0 1 127.9 10.43 24.68 137.19999999999999 19.350000000000001 15123 2012-02-21T10:00:00.000 RAW 0.38500000000000001 0.38500000000000001 -0.30499999999999999 0 0 1 127.8 12.25 25.75 144.80000000000001 25.68 15123 2012-02-21T11:00:00.000 RAW 0.46 0.46 -0.30499999999999999 0 0 1 128.1 13.86 31.47 148.9 22.73 15123 2012-02-21T12:00:00.000 RAW 0.51700000000000002 0.51700000000000002 -0.30499999999999999 0 0 1 127.9 13.53 28.64 153 25.42 15123 2012-02-21T13:00:00.000 RAW 0.88500000000000001 0.88500000000000001 -0.30499999999999999 0 0 1 128 14.62 30.08 161.19999999999999 20.79 15123 2012-02-21T14:00:00.000 RAW 1.5289999999999999 1.5289999999999999 -0.30499999999999999 0 0 1 127.7 12.87 30.9 164.2 24.84 15123 2012-02-21T15:00:00.000 RAW 2.2570000000000001 2.2570000000000001 -0.30499999999999999 0 0 1 127.3 8.64 31.09 188.6 31.73 15123 2012-02-21T16:00:00.000 RAW 2.3610000000000002 1.7070000000000001 -0.30499999999999999 0 0 1 127 7.14 26.87 194 31.94 15123 2012-02-21T17:00:00.000 RAW 2.3610000000000002 1.5649999999999999 -0.30499999999999999 0 0 1 126.7 7.88 29.13 204 35.22 15123 2012-02-21T18:00:00.000 ST 2.3610000000000002 1.018 -0.30499999999999999 0 0 1 126.6 11.73 39.200000000000003 189.2 33.17 15123 2012-02-21T19:00:00.000 RAW 1.51 1.5009999999999999 1.0169999999999999 0 0 0 126.2 16.440000000000001 34.74 163.4 28.19 15123 2012-02-21T20:00:00.000 RAW 1.9179999999999999 1.9179999999999999 1.0169999999999999 0 0 0 125.8 16.62 47.96 156.1 29.46 15123 2012-02-21T21:00:00.000 RAW 2.1349999999999998 2.1160000000000001 1.0169999999999999 0 0 0 125.3 14.87 38.14 158.9 29.91 15123 2012-02-21T22:00:00.000 RAW 2.1920000000000002 2.1259999999999999 1.0169999999999999 0 0 0 124.5 14.66 37.450000000000003 161.9 25.82 15123 2012-02-21T23:00:00.000 RAW 2.1920000000000002 1.86 1.0169999999999999 0 0 0 123.9 11.41 30.4 181.7 27.24 15123 2012-02-22T00:00:00.000 RAW 2.1920000000000002 1.804 1.0169999999999999 0 0 0 123.3 15.34 46.7 181.7 27.51 15123 2012-02-22T01:00:00.000 RAW 2.1920000000000002 1.5289999999999999 1.0169999999999999 0 0 0 122.8 17.13 39.270000000000003 168.1 28.02 15123 2012-02-22T02:00:00.000 RAW 2.1920000000000002 1.0660000000000001 1.0169999999999999 0 0 0 124.1 16.190000000000001 36.880000000000003 165.3 28.73 15123 2012-02-22T03:00:00.000 RAW 2.1920000000000002 0.77300000000000002 0.77300000000000002 0 0 0 124.1 14.64 48.65 166.4 23.5 15123 2012-02-22T04:00:00.000 RAW 2.1920000000000002 0.40400000000000003 0.40400000000000003 0 0 0 124 13.23 29.27 165.4 24.63 15123 2012-02-22T05:00:00.000 RAW 2.1920000000000002 0.14899999999999999 0.14899999999999999 0 0 0 124.2 13.24 33.67 171.6 26.54 15123 2012-02-22T06:00:00.000 ST 2.1920000000000002 -0.192 -0.192 0 0 0 124.2 13.5 32.659999999999997 173.6 21.86 15123 2012-02-22T07:00:00.000 RAW -0.192 -0.48499999999999999 -0.48499999999999999 0 0 0 123.8 7.25 29.96 210 28.19 15123 2012-02-22T08:00:00.000 RAW -0.192 -0.65500000000000003 -0.86299999999999999 0 0 0 123.7 8.2899999999999991 27.7 198.8 33.270000000000003 15123 2012-02-22T09:00:00.000 RAW -0.192 -0.75900000000000001 -0.96699999999999997 0 0 0 123.6 4.9009999999999998 37.200000000000003 205.3 49.4 15123 2012-02-22T10:00:00.000 RAW -0.106 -0.22 -0.96699999999999997 0 0 0 122.9 4.5259999999999998 20.14 203.5 32.81 15123 2012-02-22T11:00:00.000 RAW -0.106 -0.25800000000000001 -0.96699999999999997 0 0 0 122.2 9.06 22.09 183.5 25.24 15123 2012-02-22T12:00:00.000 RAW 1.86 1.86 -0.96699999999999997 0 0 1 124.8 5.7930000000000001 30.15 202.1 40.56 15123 2012-02-22T13:00:00.000 RAW 2.0299999999999998 1.109 -0.96699999999999997 0 0 1 122.3 1.8069999999999999 34.979999999999997 241.9 53.71 15123 2012-02-22T14:00:00.000 RAW 2.0299999999999998 1.4490000000000001 -0.96699999999999997 0 0 1 122.9 5.9740000000000002 43.77 251.2 40.42 15123 2012-02-22T15:00:00.000 RAW 2.16 0.76900000000000002 -0.96699999999999997 0 0 1 120.1 3.2679999999999998 21.64 233.1 42.07 15123 2012-02-22T16:00:00.000 RAW 2.7850000000000001 0.55100000000000005 -0.96699999999999997 0 0 1 122.5 10.54 42.01 221.9 37.71 15123 2012-02-22T17:00:00.000 RAW 2.7850000000000001 -0.17499999999999999 -0.96699999999999997 0 0 1 123.3 9.9 34.659999999999997 218.1 33.81 15123 2012-02-22T18:00:00.000 ST 2.7850000000000001 -1.3280000000000001 -1.385 0 0 1 123.6 5.4870000000000001 27.05 198.3 34.54 15123 2012-02-22T19:00:00.000 RAW -1.3280000000000001 -1.782 -1.782 0 0 0 122.8 6.6449999999999996 18 164.9 19.96 15123 2012-02-22T20:00:00.000 RAW -1.3280000000000001 -1.8759999999999999 -1.99 0 0 0.1 124 9.09 20.27 161.4 17.23 15123 2012-02-22T21:00:00.000 RAW -1.3280000000000001 -2.0750000000000002 -2.16 0 0 1 124.1 10.66 24.11 161.69999999999999 17.760000000000002 15123 2012-02-22T22:00:00.000 RAW -1.3280000000000001 -1.99 -2.16 0 0 1 123.9 8.8699999999999992 20.079999999999998 146.9 19.07 15123 2012-02-22T23:00:00.000 RAW -1.3280000000000001 -2.0089999999999999 -2.2549999999999999 0 0 1 123.7 8.4600000000000009 21.28 152.19999999999999 22.26 15123 2012-02-23T00:00:00.000 RAW -1.3280000000000001 -1.7050000000000001 -2.2549999999999999 0 0 1 123.2 9.0399999999999991 24.81 157.9 22.46 15123 2012-02-23T01:00:00.000 RAW -1.3280000000000001 -1.677 -2.2549999999999999 0 0 1 120.9 6.6849999999999996 20.21 150.6 17.34 15123 2012-02-23T02:00:00.000 RAW -1.3280000000000001 -1.696 -2.2549999999999999 0 0 1 121.3 8.39 16.37 148.19999999999999 16.57 15123 2012-02-23T03:00:00.000 RAW -1.3280000000000001 -2.161 -2.2549999999999999 0 0 1 122.1 8.56 19.45 142.1 19.23 15123 2012-02-23T04:00:00.000 RAW -1.3280000000000001 -2.028 -2.2549999999999999 0 0 1 122.7 9.23 17.63 143.6 15.57 15123 2012-02-23T05:00:00.000 RAW -1.3280000000000001 -2.1320000000000001 -2.2549999999999999 0 0 1 122.5 7.91 20.02 144.19999999999999 15.64 15123 2012-02-23T06:00:00.000 ST -1.3280000000000001 -2.331 -2.35 0 0 1 123.4 8.39 16.18 148.69999999999999 14.61 15123 2012-02-23T07:00:00.000 RAW -2.3029999999999999 -2.4359999999999999 -2.4359999999999999 0 0 0.1 123.7 6.1840000000000002 16.05 138.9 14.85 15123 2012-02-23T08:00:00.000 RAW -2.3029999999999999 -2.464 -2.5310000000000001 0 0 0 122.7 8.92 17.82 143.4 21.95 15123 2012-02-23T09:00:00.000 RAW -2.3029999999999999 -2.36 -2.5310000000000001 0 0 0 121.6 8.64 23.48 149.6 23.77 15123 2012-02-23T10:00:00.000 RAW -2.1419999999999999 -2.1509999999999998 -2.5310000000000001 0 0 1 124.3 8.41 19.89 143 22.04 15123 2012-02-23T11:00:00.000 RAW -1.639 -1.6679999999999999 -2.5310000000000001 0 0 1 123.4 7.63 18.32 145.9 24.19 15123 2012-02-23T12:00:00.000 RAW -0.72199999999999998 -0.78800000000000003 -2.5310000000000001 0 0 1 123.8 7.23 19.39 144.1 28.11 15123 2012-02-23T13:00:00.000 RAW -0.6 -0.67600000000000005 -2.5310000000000001 0 0 1 123.3 7.78 19.64 151.9 28.21 15123 2012-02-23T14:00:00.000 RAW -0.6 -1.3859999999999999 -2.5310000000000001 0 0 1 123.8 10.11 26.06 160 24.66 15123 2012-02-23T15:00:00.000 RAW -0.6 -1.5840000000000001 -2.5310000000000001 0 0 1 123.5 9.5 23.97 158.69999999999999 24.35 15123 2012-02-23T16:00:00.000 RAW -0.6 -1.6220000000000001 -2.5310000000000001 0 0 1 122.8 7.91 19.32 158.9 23.28 15123 2012-02-23T17:00:00.000 RAW -0.6 -1.887 -2.5310000000000001 0 0 1 123 10.01 23.41 170.3 25.46 15123 2012-02-23T18:00:00.000 ST -0.6 -2.5790000000000002 -2.589 0 0 1 122.8 9.1999999999999993 23.23 174.6 22.57 15123 2012-02-23T19:00:00.000 RAW -2.5790000000000002 -2.94 -2.968 0 0 0 121.8 9.4499999999999993 24.3 180.2 22.9 15123 2012-02-23T20:00:00.000 RAW -2.5790000000000002 -3.254 -3.2639999999999998 0 0 0 121 9.02 22.29 171.5 19.11 15123 2012-02-23T21:00:00.000 RAW -2.5790000000000002 -3.3780000000000001 -3.3780000000000001 0 0 0 120.1 6.5069999999999997 24.36 158.5 19.14 15123 2012-02-23T22:00:00.000 RAW -2.5790000000000002 -3.206 -3.492 0 0 0 121.1 3.6240000000000001 13.22 152.80000000000001 14.46 15123 2012-02-23T23:00:00.000 RAW -2.5790000000000002 -3.32 -3.492 0 0 1 123.3 2.5099999999999998 10.45 145.19999999999999 14.63 15123 2012-02-24T00:00:00.000 RAW -2.5790000000000002 -3.4159999999999999 -3.492 0 0 1 122.5 3.8290000000000002 7.93 143 11.38 15123 2012-02-24T01:00:00.000 RAW -2.5790000000000002 -3.6070000000000002 -3.6259999999999999 0 0 1 120.3 1.2170000000000001 8.69 145.6 11.51 15123 2012-02-24T02:00:00.000 RAW -2.5790000000000002 -3.359 -3.6349999999999998 0 0 3 125.3 1.288 10.33 162.6 24.17 15123 2012-02-24T03:00:00.000 RAW -2.5790000000000002 -3.3210000000000002 -3.6349999999999998 0 0 4 125.8 4.4459999999999997 16.309999999999999 150 25.55 15123 2012-02-24T04:00:00.000 RAW -2.5790000000000002 -3.4449999999999998 -3.6349999999999998 0 0 5 126.7 5.6440000000000001 17 144.69999999999999 25.78 15123 2012-02-24T05:00:00.000 RAW -2.5790000000000002 -3.6930000000000001 -3.6930000000000001 0 0 5 127 7.22 23.23 137.5 29.2 15123 2012-02-24T06:00:00.000 ST -2.5790000000000002 -3.6539999999999999 -3.702 0 0 5 126.7 7.83 21.59 132.9 24.19 15123 2012-02-24T07:00:00.000 RAW -3.5110000000000001 -3.5110000000000001 -3.6640000000000001 0 0 0.1 126.9 8.1999999999999993 23.67 134.30000000000001 21.05 15123 2012-02-24T08:00:00.000 RAW -3.3109999999999999 -3.3109999999999999 -3.6640000000000001 0 0 1 127.1 5.7220000000000004 15.61 134.80000000000001 22.58 15123 2012-02-24T09:00:00.000 RAW -1.7330000000000001 -1.8089999999999999 -3.6640000000000001 0 0 1 126.8 5.8920000000000003 14.48 134.9 16.809999999999999 15123 2012-02-24T10:00:00.000 RAW -0.93799999999999994 -1.0049999999999999 -3.6640000000000001 0 0 1 126.5 3.1880000000000002 9.6999999999999993 154.4 19.149999999999999 15123 2012-02-24T11:00:00.000 RAW -0.93799999999999994 -1.024 -3.6640000000000001 0 0 1 124.1 5.0279999999999996 13.6 161.6 20.61 15123 2012-02-24T12:00:00.000 RAW -0.68400000000000005 -1.5649999999999999 -3.6640000000000001 0 0 3 129.19999999999999 5.4340000000000002 12.78 151.1 19.3 15123 2012-02-24T13:00:00.000 RAW -0.68400000000000005 -1.081 -3.6640000000000001 0 0 7 133.1 1.4790000000000001 9.44 151.80000000000001 15.71 15123 2012-02-24T14:00:00.000 RAW -0.36199999999999999 -1.0149999999999999 -3.6640000000000001 0 0 11 136.6 8.0000000000000002E-3 0.81799999999999995 144.5 4.8109999999999999 15123 2012-02-24T15:00:00.000 RAW -0.36199999999999999 -0.72199999999999998 -3.6640000000000001 0 0 17 141.4 0 0 0 0 15123 2012-02-24T16:00:00.000 RAW -0.36199999999999999 -0.69299999999999995 -3.6640000000000001 0 0 20 144.4 0 0 0 0 15123 2012-02-24T17:00:00.000 RAW -0.36199999999999999 -0.64600000000000002 -3.6640000000000001 0 0 23 146.1 2E-3 0.441 88 2.9180000000000001 15123 2012-02-24T18:00:00.000 ST -0.36199999999999999 -1.2609999999999999 -3.6640000000000001 0 0 27 149.5 1E-3 0.126 168.4 4.0490000000000004 15123 2012-02-24T19:00:00.000 RAW -1.0329999999999999 -1.0329999999999999 -1.3939999999999999 0 0 3 151.69999999999999 3.0000000000000001E-3 0.441 234.4 5.0910000000000002 15123 2012-02-24T20:00:00.000 RAW -0.96699999999999997 -1.0620000000000001 -1.3939999999999999 0 0 5 153.69999999999999 4.0000000000000001E-3 0.441 226.2 0 15123 2012-02-24T21:00:00.000 RAW -0.96699999999999997 -1.232 -1.3939999999999999 0 0 5 150.5 1E-3 0.189 236.4 0.432 15123 2012-02-24T22:00:00.000 RAW -0.96699999999999997 -1.1559999999999999 -1.3939999999999999 0 0 5 152.5 0 0.189 241.5 0.52400000000000002 15123 2012-02-24T23:00:00.000 RAW -0.96699999999999997 -1.099 -1.3939999999999999 0 0 5 153 0 6.3E-2 238 9.9000000000000005E-2 15123 2012-02-25T00:00:00.000 RAW -0.96699999999999997 -1.327 -1.3939999999999999 0 0 6 153 4.5999999999999999E-2 2.581 240.3 8.33 15123 2012-02-25T01:00:00.000 RAW -0.96699999999999997 -1.27 -1.431 0 0 6 150.1 1.6E-2 1.385 215.3 23.14 15123 2012-02-25T02:00:00.000 RAW -0.96699999999999997 -1.1000000000000001 -1.431 0 0 6 152.69999999999999 1.0999999999999999E-2 0.81799999999999995 209.5 16.68 15123 2012-02-25T03:00:00.000 RAW -0.96699999999999997 -1.3740000000000001 -1.431 0 0 7 152.80000000000001 3.0000000000000001E-3 0.252 211.2 7.09 15123 2012-02-25T04:00:00.000 RAW -0.96699999999999997 -1.677 -1.734 0 0 7 152.9 4.9000000000000002E-2 2.6440000000000001 195.2 29.09 15123 2012-02-25T05:00:00.000 RAW -0.96699999999999997 -1.591 -1.734 0 0 8 153.5 3.5999999999999997E-2 1.637 199.1 26.5 15123 2012-02-25T06:00:00.000 ST -0.96699999999999997 -1.895 -1.9039999999999999 0 0 10 154.5 7.0999999999999994E-2 3.085 176.4 29.2 15123 2012-02-25T07:00:00.000 RAW -1.857 -1.9990000000000001 -2.0089999999999999 0 0 0 153.5 0.16 5.7919999999999998 215.8 37.35 15123 2012-02-25T08:00:00.000 RAW -1.857 -2.3029999999999999 -2.3029999999999999 0 0 0 154 0.183 3.5259999999999998 188.3 43.5 15123 2012-02-25T09:00:00.000 RAW -1.857 -2.617 -2.617 0 0 0.1 153.9 0.25700000000000001 4.9740000000000002 194.3 48.03 15123 2012-02-25T10:00:00.000 RAW -1.857 -2.95 -2.95 0 0 2 155.5 0.27900000000000003 4.5960000000000001 191.3 42.76 15123 2012-02-25T11:00:00.000 RAW -1.857 -2.95 -3.016 0 0 2 151.80000000000001 0.14599999999999999 5.6029999999999998 183.9 35.11 15123 2012-02-25T12:00:00.000 RAW -1.857 -2.6360000000000001 -3.016 0 0 3 155.80000000000001 0.19700000000000001 4.9740000000000002 171.3 33.53 15123 2012-02-25T13:00:00.000 RAW -1.4970000000000001 -1.554 -3.016 0 0 3 155.5 0.28199999999999997 7.87 155.1 37.15 15123 2012-02-25T14:00:00.000 RAW -1.4970000000000001 -2.3239999999999998 -3.016 0 0 3 149.69999999999999 0.27100000000000002 5.6660000000000004 164.2 38 15123 2012-02-25T15:00:00.000 RAW -1.4970000000000001 -2.181 -3.016 0 0 3 153.9 0.23899999999999999 5.476 146.9 34.17 15123 2012-02-25T16:00:00.000 RAW -1.4970000000000001 -2.9510000000000001 -3.016 0 0 3 154.5 0.41399999999999998 9.6300000000000008 176.1 29.77 15123 2012-02-25T17:00:00.000 RAW -1.4970000000000001 -3.742 -3.742 0 0 3 154.5 0.90800000000000003 11.58 162 40.450000000000003 15123 2012-02-25T18:00:00.000 ST -1.4970000000000001 -4.181 -4.181 0 0 4 154.69999999999999 0.92400000000000004 9.25 156.30000000000001 44.13 15123 2012-02-25T19:00:00.000 RAW -4.1719999999999997 -4.266 -4.2859999999999996 0 0 1 155.1 0.79200000000000004 10.45 155.6 45.59 15123 2012-02-25T20:00:00.000 RAW -4.1719999999999997 -4.4290000000000003 -4.4390000000000001 0 0 1 154.80000000000001 0.71399999999999997 11.4 189.7 35.909999999999997 15123 2012-02-25T21:00:00.000 RAW -4.1719999999999997 -4.5919999999999996 -4.5919999999999996 0 0 1 153.69999999999999 0.34699999999999998 5.0369999999999999 152 39.369999999999997 15123 2012-02-25T22:00:00.000 RAW -4.1719999999999997 -4.7560000000000002 -4.7560000000000002 0 0 1 151.4 0.11899999999999999 5.4779999999999998 159.19999999999999 19.579999999999998 15123 2012-02-25T23:00:00.000 RAW -4.1719999999999997 -4.9000000000000004 -4.91 0 0 1 153.69999999999999 3.1E-2 2.2669999999999999 187.1 13.92 15123 2012-02-26T00:00:00.000 RAW -4.1719999999999997 -5.0540000000000003 -5.0540000000000003 0 0 1 154.30000000000001 0.03 2.8340000000000001 220.4 1.5609999999999999 15123 2012-02-26T01:00:00.000 RAW -4.1719999999999997 -5.5369999999999999 -5.5369999999999999 0 0 1 153.30000000000001 3.0000000000000001E-3 0.75600000000000001 318 9.5500000000000007 15123 2012-02-26T02:00:00.000 RAW -4.1719999999999997 -5.8170000000000002 -5.8559999999999999 0 0 3 156.6 6.0000000000000001E-3 0.56699999999999995 296.10000000000002 7.43 15123 2012-02-26T03:00:00.000 RAW -4.1719999999999997 -6.157 -6.1959999999999997 0 0 12 165.7 1E-3 0.189 295.89999999999998 6.3630000000000004 15123 2012-02-26T04:00:00.000 RAW -4.1719999999999997 -6.8209999999999997 -6.8209999999999997 0 0 17 169.5 1.0999999999999999E-2 1.1339999999999999 332.9 8.98 15123 2012-02-26T05:00:00.000 RAW -4.1719999999999997 -7.22 -7.22 0 0 17 164.6 1E-3 0.252 356.8 4.1980000000000004 15123 2012-02-26T06:00:00.000 ST -4.1719999999999997 -7.68 -7.69 0 0 17 163.6 3.0000000000000001E-3 0.378 11.83 6.7460000000000004 15123 2012-02-26T07:00:00.000 RAW -7.68 -8.24 -8.24 0 0 4 167.5 0.11700000000000001 4.22 322.2 13.8 15123 2012-02-26T08:00:00.000 RAW -7.68 -8.36 -8.4499999999999993 0 0 5 167.7 0.13200000000000001 2.2679999999999998 322.3 19.47 15123 2012-02-26T09:00:00.000 RAW -7.68 -8.0500000000000007 -8.4499999999999993 0 0 5 165.5 0.14299999999999999 3.78 321.10000000000002 12.01 15123 2012-02-26T10:00:00.000 RAW -7.68 -7.73 -8.4499999999999993 0 0 5 166.7 0.127 3.9049999999999998 327.5 21.11 15123 2012-02-26T11:00:00.000 RAW -6.94 -6.94 -8.4499999999999993 0 0 5 166.4 1.6E-2 1.1970000000000001 305.60000000000002 9.6 15123 2012-02-26T12:00:00.000 RAW -5.4409999999999998 -6.032 -8.4499999999999993 0 0 5 165.6 9.8000000000000004E-2 3.4009999999999998 273.89999999999998 6.93 15123 2012-02-26T13:00:00.000 RAW -3.218 -3.7240000000000002 -8.4499999999999993 0 0 5 164.4 0.01 0.755 278.5 4.7519999999999998 15123 2012-02-26T14:00:00.000 RAW -3.218 -3.258 -8.4499999999999993 0 0 5 164 1.0999999999999999E-2 1.3839999999999999 280.5 5.2770000000000001 15123 2012-02-26T15:00:00.000 RAW -2.6389999999999998 -3.2109999999999999 -8.4499999999999993 0 0 5 163.80000000000001 1.7999999999999999E-2 1.1950000000000001 288.60000000000002 4.6379999999999999 15123 2012-02-26T16:00:00.000 RAW -1.7569999999999999 -4.319 -8.4499999999999993 0 0 5 163.5 9.1999999999999998E-2 2.5169999999999999 304.7 7.87 15123 2012-02-26T17:00:00.000 RAW -1.7569999999999999 -8.4700000000000006 -8.4700000000000006 0 0 5 163.9 3.464 17.489999999999998 328.4 23.39 15123 2012-02-26T18:00:00.000 ST -1.7569999999999999 -10.07 -10.07 0 0 5 163.69999999999999 2.907 13.47 337.6 25.95 15123 2012-02-26T19:00:00.000 RAW -10.07 -10.9 -10.9 0 0 0 163.4 1.6659999999999999 12.4 328.4 22.83 15123 2012-02-26T20:00:00.000 RAW -10.07 -11.83 -11.83 0 0 0 163.19999999999999 0.112 3.6539999999999999 314.39999999999998 6.5620000000000003 15123 2012-02-26T21:00:00.000 RAW -10.07 -12.17 -12.24 0 0 0 163 0.125 2.899 321.60000000000002 6.5190000000000001 15123 2012-02-26T22:00:00.000 RAW -10.07 -12.94 -12.95 0 0 0 163 4.0000000000000001E-3 0.56699999999999995 330.5 3.8119999999999998 15123 2012-02-26T23:00:00.000 RAW -10.07 -12.82 -13.16 0 0 0 162.6 0.19 5.0430000000000001 3.4750000000000001 10.1 15123 2012-02-27T00:00:00.000 RAW -10.07 -13.23 -13.23 0 0 0 162.6 0 0 0 0 15123 2012-02-27T01:00:00.000 RAW -10.07 -13.62 -13.78 0 0 0 162.19999999999999 4.0000000000000001E-3 0.69299999999999995 307.60000000000002 1.911 15123 2012-02-27T02:00:00.000 RAW -10.07 -13.68 -13.78 0 0 0 161.69999999999999 8.9999999999999993E-3 1.45 320.5 3.1960000000000002 15123 2012-02-27T03:00:00.000 RAW -10.07 -14.08 -14.08 0 0 0 161.4 5.1999999999999998E-2 1.702 316.3 4.5449999999999999 15123 2012-02-27T04:00:00.000 RAW -10.07 -14.79 -14.89 0 0 0 161.19999999999999 1.0999999999999999E-2 0.63100000000000001 307.2 4.8380000000000001 15123 2012-02-27T05:00:00.000 RAW -10.07 -14.86 -15.1 0 0 0 161 1.0999999999999999E-2 0.63100000000000001 300.5 4.2779999999999996 15123 2012-02-27T06:00:00.000 ST -10.07 -15 -15.1 0 0 0 160.69999999999999 1E-3 0.189 312.39999999999998 1.81 15123 2012-02-27T07:00:00.000 RAW -14.86 -14.86 -15.04 0 0 0 160.30000000000001 1E-3 0.126 326.5 0 15123 2012-02-27T08:00:00.000 RAW -14.38 -14.38 -15.04 0 0 0 159.9 1E-3 0.126 321.5 1.32 15123 2012-02-27T09:00:00.000 RAW -13.49 -13.49 -15.04 0 0 0 159.6 6.0000000000000001E-3 0.75700000000000001 298.5 3.8239999999999998 15123 2012-02-27T10:00:00.000 RAW -11.25 -11.32 -15.04 0 0 0 159.30000000000001 0 6.3E-2 302.5 0.57399999999999995 15123 2012-02-27T11:00:00.000 RAW -10.1 -10.1 -15.04 0 0 0 159.4 0 0 0 0 15123 2012-02-27T12:00:00.000 RAW -4.6980000000000004 -4.7069999999999999 -15.04 0 0 0 157.6 0 0 0 0 15123 2012-02-27T13:00:00.000 RAW -2.419 -3.2959999999999998 -15.04 0 0 0 158.19999999999999 8.0000000000000002E-3 0.504 315.7 9.27 15123 2012-02-27T14:00:00.000 RAW -1.246 -1.246 -15.04 0 0 0 157.80000000000001 7.8E-2 5.3470000000000004 280.60000000000002 23.71 15123 2012-02-27T15:00:00.000 RAW -0.82899999999999996 -0.82899999999999996 -15.04 0 0 0 157.69999999999999 0.04 4.1520000000000001 279.2 22.71 15123 2012-02-27T16:00:00.000 RAW 1.006 -0.40300000000000002 -15.04 0 0 0 157.19999999999999 0 0.126 312.2 5.2080000000000002 15123 2012-02-27T17:00:00.000 RAW 1.006 -5.28 -15.04 0 0 0 158.6 0.183 4.2789999999999999 40.78 27.3 15123 2012-02-27T18:00:00.000 ST 1.006 -6.4809999999999999 -15.04 0 0 0 158.69999999999999 2.68 17.37 94.7 24.29 15123 2012-02-27T19:00:00.000 RAW -6.4809999999999999 -6.6840000000000002 -6.7140000000000004 0 0 0 157.5 1.3120000000000001 9.76 62.82 14.29 15123 2012-02-27T20:00:00.000 RAW -6.4809999999999999 -7.08 -7.08 0 0 0 156.9 0.01 1.1970000000000001 49.23 5.0019999999999998 15123 2012-02-27T21:00:00.000 RAW -6.4809999999999999 -7.44 -7.44 0 0 0 156.80000000000001 1.5880000000000001 8.8800000000000008 71.7 18.72 15123 2012-02-27T22:00:00.000 RAW -6.4809999999999999 -7.59 -7.67 0 0 0 156.6 2.21 8.32 70.900000000000006 40.590000000000003 15123 2012-02-27T23:00:00.000 RAW -6.4809999999999999 -7.39 -7.67 0 0 0 156.19999999999999 0.69199999999999995 8 314.8 36.909999999999997 15123 2012-02-28T00:00:00.000 RAW -6.4809999999999999 -7.62 -7.67 0 0 0 156.19999999999999 0.377 7.12 288.60000000000002 2.2050000000000001 15123 2012-02-28T01:00:00.000 RAW -6.4809999999999999 -7.6 -7.67 0 0 0 155.9 1E-3 0.189 283 0.88400000000000001 15123 2012-02-28T02:00:00.000 RAW -6.4809999999999999 -7.42 -7.67 0 0 0 155.69999999999999 1.145 8.6300000000000008 65.5 32.46 15123 2012-02-28T03:00:00.000 RAW -6.4809999999999999 -7.82 -7.82 0 0 0 155.5 0.219 5.1029999999999998 291 3.6589999999999998 15123 2012-02-28T04:00:00.000 RAW -6.4809999999999999 -8.1300000000000008 -8.16 0 0 0 155.30000000000001 2.5000000000000001E-2 2.0790000000000002 331.5 23.86 15123 2012-02-28T05:00:00.000 RAW -6.4809999999999999 -7.99 -8.16 0 0 0 155.30000000000001 8.9999999999999993E-3 0.88200000000000001 302.39999999999998 8.57 15123 2012-02-28T06:00:00.000 ST -6.4809999999999999 -8.02 -8.16 0 0 0 155 0 6.3E-2 293.3 0.47599999999999998 15123 2012-02-28T07:00:00.000 RAW -7.82 -7.83 -8.08 0 0 0 154.80000000000001 5.5E-2 3.024 299.8 0.77500000000000002 15123 2012-02-28T08:00:00.000 RAW -6.9080000000000004 -6.9080000000000004 -8.08 0 0 0 154.80000000000001 0 0 0 0 15123 2012-02-28T09:00:00.000 RAW -5.3810000000000002 -5.3810000000000002 -8.08 0 0 0 154.4 0 0 0 0 15123 2012-02-28T10:00:00.000 RAW -3.0150000000000001 -3.0339999999999998 -8.08 0 0 0 153.5 0 0 0 0 15123 2012-02-28T11:00:00.000 RAW -1.5549999999999999 -1.64 -8.08 0 0 0 153.5 0 0 0 0 15123 2012-02-28T12:00:00.000 RAW 0.40200000000000002 0.29799999999999999 -8.08 0 0 0 152.1 0 0 0 0 15123 2012-02-28T13:00:00.000 RAW 0.94899999999999995 0.94899999999999995 -8.08 0 0 0 152.1 0 6.3E-2 271.39999999999998 1E-3 15123 2012-02-28T14:00:00.000 RAW 1.0720000000000001 0.39 -8.08 0 0 0 152.1 0 6.3E-2 276.8 0 15123 2012-02-28T15:00:00.000 RAW 1.0720000000000001 0.26800000000000002 -8.08 0 0 0 152.1 0 0 0 0 15123 2012-02-28T16:00:00.000 RAW 1.0720000000000001 -1.008 -8.08 0 0 0 153.30000000000001 0 0 0 0 15123 2012-02-28T17:00:00.000 RAW 1.0720000000000001 -1.784 -8.08 0 0 0 153.4 0 0 0 0 15123 2012-02-28T18:00:00.000 ST 1.0720000000000001 -3.0739999999999998 -8.08 0 0 0 152.9 0.83899999999999997 9.6300000000000008 99 3.109 15123 2012-02-28T19:00:00.000 RAW -3.0270000000000001 -3.5880000000000001 -3.5880000000000001 0 0 0 151.80000000000001 0.90400000000000003 9.51 92.1 5.431 15123 2012-02-28T20:00:00.000 RAW -3.0270000000000001 -4.2380000000000004 -4.2480000000000002 0 0 0 153 1.0840000000000001 12.53 93.1 6.3090000000000002 15123 2012-02-28T21:00:00.000 RAW -3.0270000000000001 -4.6790000000000003 -4.718 0 0 0 153.1 0.10299999999999999 5.8550000000000004 87.7 4.6449999999999996 15123 2012-02-28T22:00:00.000 RAW -3.0270000000000001 -4.7649999999999997 -4.9390000000000001 0 0 0 152.69999999999999 0 6.3E-2 291 3.0000000000000001E-3 15123 2012-02-28T23:00:00.000 RAW -3.0270000000000001 -4.7359999999999998 -4.9390000000000001 0 0 0 152.30000000000001 2.1000000000000001E-2 1.133 339 2.42 15123 2012-02-29T00:00:00.000 RAW -3.0270000000000001 -4.9089999999999998 -4.9390000000000001 0 0 0 152.19999999999999 5.6000000000000001E-2 2.33 8.14 2.5979999999999999 15123 2012-02-29T01:00:00.000 RAW -3.0270000000000001 -5.024 -5.0629999999999997 0 0 0 152 7.2999999999999995E-2 2.5819999999999999 15.78 5.1379999999999999 15123 2012-02-29T02:00:00.000 RAW -3.0270000000000001 -5.14 -5.1980000000000004 0 0 0 151.9 6.0000000000000001E-3 0.94499999999999995 38.14 8.8699999999999992 15123 2012-02-29T03:00:00.000 RAW -3.0270000000000001 -5.0529999999999999 -5.1980000000000004 0 0 0 148.6 2.1000000000000001E-2 2.2040000000000002 354.6 8.7799999999999994 15123 2012-02-29T04:00:00.000 RAW -3.0270000000000001 -5.0819999999999999 -5.1980000000000004 0 0 0 152.19999999999999 6.0000000000000001E-3 0.75600000000000001 14.89 1.345 15123 2012-02-29T05:00:00.000 RAW -3.0270000000000001 -5.2560000000000002 -5.2560000000000002 0 0 0 151.30000000000001 0 0 0 0 15123 2012-02-29T06:00:00.000 ST -3.0270000000000001 -5.3710000000000004 -5.4489999999999998 0 0 0 151.19999999999999 0 0 0 0 15123 2012-02-29T07:00:00.000 RAW -5.2359999999999998 -5.5359999999999996 -5.5359999999999996 0 0 0 150.69999999999999 0 0.189 187.3 0 15123 2012-02-29T08:00:00.000 RAW -5.1210000000000004 -5.1210000000000004 -5.633 0 0 0 150.30000000000001 1E-3 0.252 173.2 0.94599999999999995 15123 2012-02-29T09:00:00.000 RAW -3.6629999999999998 -3.71 -5.633 0 0 0 150 0 6.3E-2 183 0 15123 2012-02-29T10:00:00.000 RAW -1.4490000000000001 -1.4490000000000001 -5.633 0 0 0 149.6 0 0 0 0 15123 2012-02-29T11:00:00.000 RAW 0.38600000000000001 -0.107 -5.633 0 0 0 147.19999999999999 0 6.3E-2 128.30000000000001 0 15123 2012-02-29T12:00:00.000 RAW 2.891 1.7909999999999999 -5.633 0 0 0 147 1E-3 0.189 244.4 1.5029999999999999 15123 2012-02-29T13:00:00.000 RAW 2.891 0.44400000000000001 -5.633 0 0 0 149.1 2.1999999999999999E-2 2.5779999999999998 168.4 1.2470000000000001 15123 2012-02-29T14:00:00.000 RAW 2.891 1.004 -5.633 0 0 0 149 0.29399999999999998 5.7850000000000001 187.6 7.72 15123 2012-02-29T15:00:00.000 RAW 2.891 -0.129 -5.633 0 0 0 149.4 4.8000000000000001E-2 2.5779999999999998 187.8 1.8520000000000001 15123 2012-02-29T16:00:00.000 RAW 2.891 -2.0790000000000002 -5.633 0 0 0.1 151.1 1.119 9.69 169.4 13.68 15123 2012-02-29T17:00:00.000 RAW 2.891 -3.0270000000000001 -5.633 0 0 1 151.4 8.5000000000000006E-2 4.3410000000000002 161.5 5.4889999999999999 15123 2012-02-29T18:00:00.000 ST 2.891 -3.875 -5.633 0 0 1 151.80000000000001 0 0 0 0 15123 2012-02-29T19:00:00.000 RAW -3.8559999999999999 -4.1230000000000002 -4.1230000000000002 0 0 0 151.5 0 6.3E-2 142.6 0 15123 2012-02-29T20:00:00.000 RAW -3.8559999999999999 -4.8620000000000001 -4.8620000000000001 0 0 0 150.80000000000001 1E-3 0.252 169.5 0.59299999999999997 15123 2012-02-29T21:00:00.000 RAW -3.8559999999999999 -4.8710000000000004 -5.0449999999999999 0 0 0 150.80000000000001 0.34100000000000003 4.8490000000000002 149.5 7.15 15123 2012-02-29T22:00:00.000 RAW -3.8559999999999999 -4.3520000000000003 -5.0640000000000001 0 0 0 150.80000000000001 0.55300000000000005 5.9189999999999996 163.1 8.3000000000000007 15123 2012-02-29T23:00:00.000 RAW -3.8559999999999999 -4.2370000000000001 -5.0640000000000001 0 0 0 150.69999999999999 0.51200000000000001 6.9269999999999996 149.30000000000001 16.940000000000001 15123 2012-03-01T00:00:00.000 RAW -3.8559999999999999 -4.3529999999999998 -5.0640000000000001 0 0 0 150.5 0.83099999999999996 5.73 147 10.37 15123 2012-03-01T01:00:00.000 RAW -3.8559999999999999 -4.2370000000000001 -5.0640000000000001 0 0 0 150.5 1.7789999999999999 8.25 148.9 11.14 15123 2012-03-01T02:00:00.000 RAW -3.8559999999999999 -4.3049999999999997 -5.0640000000000001 0 0 0 150.30000000000001 1.694 8.5 150.9 11.69 15123 2012-03-01T03:00:00.000 RAW -3.8559999999999999 -4.2859999999999996 -5.0640000000000001 0 0 0 151 1.54 10.01 165.1 16.7 15123 2012-03-01T04:00:00.000 RAW -3.8559999999999999 -4.6020000000000003 -5.0640000000000001 0 0 0 151.1 0.56200000000000006 7.56 159.9 9.3699999999999992 15123 2012-03-01T05:00:00.000 RAW -3.8559999999999999 -4.7069999999999999 -5.0640000000000001 0 0 0 151 0.246 4.66 156.1 10.7 15123 2012-03-01T06:00:00.000 ST -3.8559999999999999 -4.5250000000000004 -5.0640000000000001 0 0 0 150.80000000000001 0.34300000000000003 5.92 153.69999999999999 12.81 15123 2012-03-01T07:00:00.000 RAW -4.41 -4.41 -4.5250000000000004 0 0 0 150.6 0.41499999999999998 5.8570000000000002 170.6 10.52 15123 2012-03-01T08:00:00.000 RAW -4.1130000000000004 -4.1130000000000004 -4.5250000000000004 0 0 0 150.5 2.7E-2 2.141 184.5 3.8620000000000001 15123 2012-03-01T09:00:00.000 RAW -3.5110000000000001 -3.5209999999999999 -4.5250000000000004 0 0 0 150.19999999999999 6.6000000000000003E-2 1.952 183.8 8.18 15123 2012-03-01T10:00:00.000 RAW -2.6349999999999998 -2.6829999999999998 -4.5250000000000004 0 0 0 150.1 0.41899999999999998 6.2969999999999997 165.8 19.399999999999999 15123 2012-03-01T11:00:00.000 RAW -1.734 -1.839 -4.5250000000000004 0 0 0 149.9 1.1419999999999999 6.359 164.1 14.79 15123 2012-03-01T12:00:00.000 RAW 0.52600000000000002 0.41299999999999998 -4.5250000000000004 0 0 0 148.80000000000001 3.1680000000000001 13.66 152.69999999999999 19.27 15123 2012-03-01T13:00:00.000 RAW 1.6220000000000001 0.874 -4.5250000000000004 0 0 0 148.4 5.14 14.72 150.9 21.42 15123 2012-03-01T14:00:00.000 RAW 1.657 0.85299999999999998 -4.5250000000000004 0 0 0 148.19999999999999 8.64 18.55 156.19999999999999 23.7 15123 2012-03-01T15:00:00.000 RAW 1.657 7.6999999999999999E-2 -4.5250000000000004 0 0 0 148.5 7.83 18.36 150.6 23.36 15123 2012-03-01T16:00:00.000 RAW 1.657 0.221 -4.5250000000000004 0 0 0 147.80000000000001 6.3650000000000002 18.989999999999998 151.80000000000001 21.88 15123 2012-03-01T17:00:00.000 RAW 1.657 -2.5739999999999998 -4.5250000000000004 0 0 0 149.4 4.6470000000000002 14.47 145.69999999999999 22.71 15123 2012-03-01T18:00:00.000 ST 1.657 -3.7240000000000002 -4.5250000000000004 0 0 0 149.4 6.4210000000000003 16.170000000000002 139.69999999999999 17.850000000000001 15123 2012-03-01T19:00:00.000 RAW -3.7240000000000002 -3.9129999999999998 -3.9239999999999999 0 0 0 149.19999999999999 6.6920000000000002 17.809999999999999 132.6 17.03 15123 2012-03-01T20:00:00.000 RAW -3.7240000000000002 -3.8929999999999998 -3.99 0 0 0 149 9.8699999999999992 19.2 145.69999999999999 14.89 15123 2012-03-01T21:00:00.000 RAW -3.7240000000000002 -3.96 -3.99 0 0 0 148.9 10.23 19.64 149.80000000000001 17.02 15123 2012-03-01T22:00:00.000 RAW -3.7240000000000002 -3.8740000000000001 -3.99 0 0 0 148.69999999999999 9.39 19.14 150.19999999999999 20.45 15123 2012-03-01T23:00:00.000 RAW -3.7240000000000002 -3.8929999999999998 -3.99 0 0 0 148.69999999999999 8.0500000000000007 23.05 146.5 19.05 15123 2012-03-02T00:00:00.000 RAW -3.7240000000000002 -3.8069999999999999 -3.99 0 0 0 148.5 9.8800000000000008 20.78 146.4 19.170000000000002 15123 2012-03-02T01:00:00.000 RAW -3.7109999999999999 -3.7210000000000001 -3.99 0 0 0 148.1 10.02 25.38 150.19999999999999 21.78 15123 2012-03-02T02:00:00.000 RAW -3.625 -3.673 -3.99 0 0 0 148.69999999999999 9.36 23.05 159.6 18.32 15123 2012-03-02T03:00:00.000 RAW -3.5019999999999998 -3.5209999999999999 -3.99 0 0 0 148.30000000000001 9.9 22.86 157.9 19.63 15123 2012-03-02T04:00:00.000 RAW -3.4060000000000001 -3.4159999999999999 -3.99 0 0 0 148.30000000000001 10.29 24.3 156.19999999999999 21.21 15123 2012-03-02T05:00:00.000 RAW -3.3490000000000002 -3.3580000000000001 -3.99 0 0 0 147.80000000000001 9.01 19.2 145.69999999999999 21.63 15123 2012-03-02T06:00:00.000 ST -3.3109999999999999 -3.33 -3.99 0 0 0 148.19999999999999 9.86 28.4 149.30000000000001 24.81 15123 2012-03-02T07:00:00.000 RAW -3.2160000000000002 -3.2160000000000002 -3.339 0 0 0.1 148.6 10.31 22.29 152 26.04 15123 2012-03-02T08:00:00.000 RAW -2.9969999999999999 -3.0059999999999998 -3.339 0 0 0 146.5 11.42 30.6 158.69999999999999 28.78 15123 2012-03-02T09:00:00.000 RAW -2.6920000000000002 -2.702 -3.339 0 0 1 149.1 12.54 32.74 155.80000000000001 27.99 15123 2012-03-02T10:00:00.000 RAW -2.5209999999999999 -2.54 -3.339 0 0 1 149.19999999999999 11.07 26.13 148.1 27.95 15123 2012-03-02T11:00:00.000 RAW -1.6870000000000001 -1.772 -3.339 0 0 1 148.9 10.93 29.65 149.80000000000001 28.23 15123 2012-03-02T12:00:00.000 RAW -1.4890000000000001 -1.4890000000000001 -3.339 0 0 1 148.1 10.119999999999999 23.98 144.19999999999999 27.77 15123 2012-03-02T13:00:00.000 RAW -1.177 -1.2430000000000001 -3.339 0 0 1 149.19999999999999 10.9 23.16 142.6 26.61 15123 2012-03-02T14:00:00.000 RAW -1.167 -1.423 -3.339 0 0 2 149.5 9.67 25.62 143.4 28.73 15123 2012-03-02T15:00:00.000 RAW -1.167 -1.754 -3.339 0 0 2 149.6 9.23 25.68 147.30000000000001 26.07 15123 2012-03-02T16:00:00.000 RAW -1.167 -1.7629999999999999 -3.339 0 0 2 146.69999999999999 6.5250000000000004 17.440000000000001 145.4 24.32 15123 2012-03-02T17:00:00.000 RAW -1.167 -1.867 -3.339 0 0 2 149.69999999999999 7.82 17.940000000000001 143.19999999999999 19.91 15123 2012-03-02T18:00:00.000 ST -1.167 -2.1419999999999999 -3.339 0 0 2 149.9 8.8699999999999992 28.39 151.80000000000001 22.15 15123 2012-03-02T19:00:00.000 RAW -2.028 -2.0379999999999998 -2.161 0 0 0 150.1 8.2899999999999991 19.45 153.1 24.34 15123 2012-03-02T20:00:00.000 RAW -1.857 -1.9039999999999999 -2.161 0 0 0.1 150.19999999999999 9.61 26.06 160.80000000000001 23.12 15123 2012-03-02T21:00:00.000 RAW -1.857 -1.895 -2.161 0 0 0.1 150.1 10.91 28.46 152.1 23.78 15123 2012-03-02T22:00:00.000 RAW -1.724 -1.724 -2.161 0 0 0.1 150 11.33 37.9 152.9 25.98 15123 2012-03-02T23:00:00.000 RAW -1.3169999999999999 -1.3360000000000001 -2.161 0 0 0 149.4 10.29 27.32 146.80000000000001 26.54 15123 2012-03-03T00:00:00.000 RAW -1.0609999999999999 -1.0609999999999999 -2.161 0 0 0 148.6 8.8699999999999992 31.42 138.4 29.81 15123 2012-03-03T01:00:00.000 RAW -1.042 -1.1180000000000001 -2.161 0 0 0 149.30000000000001 10.08 30.85 149.1 29.93 15123 2012-03-03T02:00:00.000 RAW -0.91 -0.93799999999999994 -2.161 0 0 0 149.19999999999999 12.57 31.48 153 30.47 15123 2012-03-03T03:00:00.000 RAW -0.89100000000000001 -1.042 -2.161 0 0 0 149.5 12.01 41.99 149.69999999999999 33.96 15123 2012-03-03T04:00:00.000 RAW -0.74 -0.74 -2.161 0 0 0 149.5 11.95 35.26 156.5 31.54 15123 2012-03-03T05:00:00.000 RAW -0.56899999999999995 -0.57899999999999996 -2.161 0 0 0 148.80000000000001 13.64 28.71 157.30000000000001 25.6 15123 2012-03-03T06:00:00.000 ST -0.39900000000000002 -0.39900000000000002 -2.161 0 0 0 149.19999999999999 14.87 32.86 161.1 28.29 15123 2012-03-03T07:00:00.000 RAW -0.23799999999999999 -0.26700000000000002 -0.39900000000000002 0 0 0.1 149.6 17.75 36.07 164.5 25.35 15123 2012-03-03T08:00:00.000 RAW 4.5999999999999999E-2 4.5999999999999999E-2 -0.39900000000000002 0 0 0.1 149.5 14.86 39.03 155.5 24.24 15123 2012-03-03T09:00:00.000 RAW 0.66900000000000004 0.66900000000000004 -0.39900000000000002 0 0 0.1 149.5 16.13 37.520000000000003 165.4 23.34 15123 2012-03-03T10:00:00.000 RAW 1.4350000000000001 1.4350000000000001 -0.39900000000000002 0 0 0 149 15.03 32.92 164.5 25.07 15123 2012-03-03T11:00:00.000 RAW 1.9930000000000001 1.9930000000000001 -0.39900000000000002 0 0 0 148.19999999999999 15.41 36.380000000000003 164.9 27.18 15123 2012-03-03T12:00:00.000 RAW 2.6739999999999999 2.665 -0.39900000000000002 0 0 0 147.19999999999999 14.69 39.4 168.6 29.82 15123 2012-03-03T13:00:00.000 RAW 2.8540000000000001 2.6829999999999998 -0.39900000000000002 0 0 0 146.80000000000001 15.04 34.04 167.3 27.28 15123 2012-03-03T14:00:00.000 RAW 3.0619999999999998 2.91 -0.39900000000000002 0 0 0 145 15.07 34.479999999999997 166.1 30.11 15123 2012-03-03T15:00:00.000 RAW 3.0619999999999998 2.7869999999999999 -0.39900000000000002 0 0 0 144.9 14.87 40.14 164.8 28.08 15123 2012-03-03T16:00:00.000 RAW 3.0619999999999998 2.3039999999999998 -0.39900000000000002 0 0 0 143.9 15.44 38.380000000000003 158.5 31.52 15123 2012-03-03T17:00:00.000 RAW 3.0619999999999998 2.0209999999999999 -0.39900000000000002 0 0 0 144.1 16.239999999999998 41.66 162.4 30.86 15123 2012-03-03T18:00:00.000 ST 3.0619999999999998 1.8029999999999999 -0.39900000000000002 0 0 0 143 14.83 42.73 153.19999999999999 31.75 15123 2012-03-03T19:00:00.000 RAW 1.87 1.87 1.746 0 0 0 143 15.25 39.33 153.30000000000001 31.53 15123 2012-03-03T20:00:00.000 RAW 1.88 1.861 1.746 0 0 0 142.5 16.059999999999999 33.61 159.69999999999999 29.68 15123 2012-03-03T21:00:00.000 RAW 1.889 1.87 1.746 0 0 0 141.5 13.54 34.36 159.69999999999999 30.42 15123 2012-03-03T22:00:00.000 RAW 1.8979999999999999 1.861 1.746 0 0 0 142.1 14.3 37.51 157.9 28.99 15123 2012-03-03T23:00:00.000 RAW 1.8979999999999999 1.766 1.746 0 0 0 141.69999999999999 12.69 33.92 157.19999999999999 30.56 15123 2012-03-04T00:00:00.000 RAW 1.8979999999999999 1.605 1.5860000000000001 0 0 0 141 13.23 29.01 153.5 29.13 15123 2012-03-04T01:00:00.000 RAW 1.8979999999999999 1.5109999999999999 1.492 0 0 0 141 14.56 34.43 157.6 29.09 15123 2012-03-04T02:00:00.000 RAW 1.8979999999999999 1.5009999999999999 1.444 0 0 0 140.5 17.850000000000001 40.47 165.8 27.02 15123 2012-03-04T03:00:00.000 RAW 1.8979999999999999 1.52 1.444 0 0 0 140.1 19 47.83 169.2 29.01 15123 2012-03-04T04:00:00.000 RAW 1.8979999999999999 1.359 1.34 0 0 0 139.9 18.36 40.409999999999997 166 26 15123 2012-03-04T05:00:00.000 RAW 1.8979999999999999 1.2649999999999999 1.2549999999999999 0 0 0 139.5 19.489999999999998 36.5 167.8 26.11 15123 2012-03-04T06:00:00.000 ST 1.8979999999999999 1.075 1.0660000000000001 0 0 0 138.69999999999999 13.47 32.159999999999997 159.19999999999999 27.51 15123 2012-03-04T07:00:00.000 RAW 1.085 0.85799999999999998 0.84899999999999998 0 0 0 138.9 12.65 33.549999999999997 161.4 25.71 15123 2012-03-04T08:00:00.000 RAW 1.085 0.89600000000000002 0.83899999999999997 0 0 0.1 139 14.83 35.06 166.8 24.52 15123 2012-03-04T09:00:00.000 RAW 1.161 1.161 0.83899999999999997 0 0 0.1 138.9 14.4 34.24 167.8 25.7 15123 2012-03-04T10:00:00.000 RAW 1.5389999999999999 1.5389999999999999 0.83899999999999997 0 0 0.1 139 14.4 37.89 170.5 26.87 15123 2012-03-04T11:00:00.000 RAW 2.0779999999999998 2.0779999999999998 0.83899999999999997 0 0 0.1 138.9 13.21 34.93 174.4 29.69 15123 2012-03-04T12:00:00.000 RAW 3.6520000000000001 3.5950000000000002 0.83899999999999997 0 0 0 138.30000000000001 11.44 30.33 184 30 15123 2012-03-04T13:00:00.000 RAW 3.8220000000000001 3.2890000000000001 0.83899999999999997 0 0 0 137.9 13.88 34.29 176.4 28.92 15123 2012-03-04T14:00:00.000 RAW 3.8220000000000001 3.4319999999999999 0.83899999999999997 0 0 0 137.1 14.22 40.83 174.3 27.91 15123 2012-03-04T15:00:00.000 RAW 3.9350000000000001 3.052 0.83899999999999997 0 0 0 137 10.11 31.83 171.2 30.08 15123 2012-03-04T16:00:00.000 RAW 3.9350000000000001 2.0089999999999999 0.83899999999999997 0 0 0 136.80000000000001 8.93 23.59 182.1 27.89 15123 2012-03-04T17:00:00.000 RAW 3.9350000000000001 0.85599999999999998 0.83899999999999997 0 0 0 136.6 12.4 29.44 165.8 26.52 15123 2012-03-04T18:00:00.000 ST 3.9350000000000001 0.46 0.46 0 0 0 136.4 11.74 26.55 162.30000000000001 24.14 15123 2012-03-04T19:00:00.000 RAW 0.46899999999999997 0.224 0.215 0 0 0 136.30000000000001 12.19 26.24 158.9 21.31 15123 2012-03-04T20:00:00.000 RAW 0.46899999999999997 -1.2E-2 -3.1E-2 0 0 0 135.9 11.95 30.21 153.1 26.11 15123 2012-03-04T21:00:00.000 RAW 0.46899999999999997 -0.192 -0.20100000000000001 0 0 0 135.9 11.36 22.41 153 19.98 15123 2012-03-04T22:00:00.000 RAW 0.46899999999999997 -0.35199999999999998 -0.35199999999999998 0 0 0 135.1 10.64 22.6 151.19999999999999 19.239999999999998 15123 2012-03-04T23:00:00.000 RAW 0.46899999999999997 -0.40899999999999997 -0.41799999999999998 0 0 0 134 9.19 20.71 150.6 16.39 15123 2012-03-05T00:00:00.000 RAW 0.46899999999999997 -0.56000000000000005 -0.56000000000000005 0 0 0 134.19999999999999 6.5629999999999997 15.67 148.4 13.79 15123 2012-03-05T01:00:00.000 RAW 0.46899999999999997 -0.74 -0.82499999999999996 0 0 0 136.30000000000001 6.9829999999999997 17 145.19999999999999 17.079999999999998 15123 2012-03-05T02:00:00.000 RAW 0.46899999999999997 -1.0049999999999999 -1.0429999999999999 0 0 2 138.1 5.556 16.18 147.80000000000001 19.27 15123 2012-03-05T03:00:00.000 RAW 0.46899999999999997 -1.081 -1.2230000000000001 0 0 2 137.19999999999999 4.5309999999999997 13.72 146.9 20.14 15123 2012-03-05T04:00:00.000 RAW 0.46899999999999997 -1.298 -1.4119999999999999 0 0 3 138.80000000000001 5.1669999999999998 13.28 151.1 20.2 15123 2012-03-05T05:00:00.000 RAW 0.46899999999999997 -1.3740000000000001 -1.431 0 0 4 139.30000000000001 6.5339999999999998 12.34 149.80000000000001 20.399999999999999 15123 2012-03-05T06:00:00.000 ST 0.46899999999999997 -1.298 -1.431 0 0 4 138.80000000000001 6.8360000000000003 14.48 151.19999999999999 17.38 15123 2012-03-05T07:00:00.000 RAW -1.2410000000000001 -1.706 -1.706 0 0 0 138.5 5.532 14.67 153.5 16.239999999999998 15123 2012-03-05T08:00:00.000 RAW -1.2410000000000001 -1.516 -1.772 0 0 6 144.6 3.234 10.39 150.5 13.67 15123 2012-03-05T09:00:00.000 RAW -1.2410000000000001 -3.3119999999999998 -3.3119999999999998 0 0 8 146.6 0.24099999999999999 4.407 57.07 13.78 15123 2012-03-05T10:00:00.000 RAW -1.2410000000000001 -3.76 -3.76 0 0 10 148.30000000000001 2.4700000000000002 11.21 33.44 38.020000000000003 15123 2012-03-05T11:00:00.000 RAW -1.2410000000000001 -4.0469999999999997 -4.0949999999999998 0 0 17 154.5 5.875 15.93 22.83 32.75 15123 2012-03-05T12:00:00.000 RAW -1.2410000000000001 -4.6029999999999998 -4.6029999999999998 0 0 23 159.9 8.11 21.97 17.55 30.6 15123 2012-03-05T13:00:00.000 RAW -1.2410000000000001 -4.3730000000000002 -4.6509999999999998 0 0 27 164.1 7.19 15.55 24.83 26.96 15123 2012-03-05T14:00:00.000 RAW -1.2410000000000001 -3.3969999999999998 -4.6509999999999998 0 0 29 164.6 4.0830000000000002 18.64 35.9 26.7 15123 2012-03-05T15:00:00.000 RAW -1.2410000000000001 -5.0369999999999999 -5.0369999999999999 0 0 29 163.9 3.7 13.6 34.75 36.950000000000003 15123 2012-03-05T16:00:00.000 RAW -1.2410000000000001 -5.6539999999999999 -5.7220000000000004 0 0 29 163.69999999999999 7.95 17.63 26.52 31.15 15123 2012-03-05T17:00:00.000 RAW -1.2410000000000001 -6.2750000000000004 -6.2850000000000001 0 0 29 163.69999999999999 9.19 19.2 16.559999999999999 28.27 15123 2012-03-05T18:00:00.000 ST -1.2410000000000001 -6.4210000000000003 -6.48 0 0 35 169.1 7.22 18.260000000000002 13.49 27.26 15123 2012-03-05T19:00:00.000 RAW -6.3819999999999997 -6.45 -6.47 0 0 2 171.1 1.536 10.52 5.2910000000000004 24.43 15123 2012-03-05T20:00:00.000 RAW -6.3819999999999997 -6.6150000000000002 -6.6150000000000002 0 0 2 170.6 0.51700000000000002 5.101 358.4 18.670000000000002
0 3 26 14 False False weatherdata Simple Text 1252 . , AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat AutoFormat
ox-2.14.17/test/weather/README000066400000000000000000000003031445411231300156040ustar00rootroot00000000000000 To run the example, cd to the ox/test directory and execute the command weather/perf_weather.rb Browse the sample parser files in the ox/test/weather directory to see how each parser is used. ox-2.14.17/test/weather/perf_weather.rb000077500000000000000000000040631445411231300177360ustar00rootroot00000000000000#!/usr/bin/env ruby -wW1 # This example uses SAX and DOM approaches to parsing XML files. It is also # used to compare the differences in performance and code structure for # multiple XML parsers. # # Weather files taken from the British of Columbia are used as a source for # capturing the high temperatures over some period of time. The files are # loaded into a spreadsheet and then dumped as XML. The high temperatures for # each time is stored in a Hash but no further action is taken on the data. $: << File.dirname(__FILE__) $: << File.join(File.dirname(__FILE__), '..') $: << File.join(File.dirname(__FILE__), '../../lib') $: << File.join(File.dirname(__FILE__), '../../ext') require 'optparse' require 'perf' $filename = 'weather/HellsGate_2012_weather.xml' $as_time = false $iter = 10 opts = OptionParser.new opts.on('-f', '--file [String]', String, 'filename') { |f| $filename = f } opts.on('-i', '--iterations [Int]', Integer, 'iterations') { |i| $iter = i } opts.on('-t', 'dates as time') { $as_time = true } opts.on('-h', '--help', 'Show this display') { puts opts; Process.exit!(0) } rest = opts.parse(ARGV) perf = Perf.new $sax = nil begin require 'weather/wsax' perf.add('Ox::Sax', 'sax_parse') { Weather::WSax.parse($filename, $as_time) } rescue Exception => e end begin require 'weather/wox' perf.add('Ox', 'parse') { Weather::WOx.parse($filename, $as_time) } rescue Exception => e end begin require 'weather/wnosax' perf.add('Nokogiri::XML::Sax', 'parse') { Weather::WNoSax.parse($filename, $as_time) } rescue Exception => e end begin require 'weather/wno' perf.add('Nokogiri::XML::Document', 'parse') { Weather::WNo.parse($filename, $as_time) } rescue Exception => e end begin require 'weather/wlxsax' perf.add('LibXML::XML::SaxParser', 'parse') { Weather::WLxSax.parse($filename, $as_time) } rescue Exception => e end begin require 'weather/wlx' perf.add('LibXML::XML::Document', 'parse') { Weather::WLx.parse($filename, $as_time) } rescue Exception => e end perf.run($iter) ox-2.14.17/test/weather/wlx.rb000066400000000000000000000020521445411231300160660ustar00rootroot00000000000000require 'time' require 'libxml' module Weather class WLx def self.parse(filename, as_time) highs = {} doc = LibXML::XML::Document.file(filename) ws = nil table = nil doc.root.each_element do |e| if 'Worksheet' == e.name ws = e break end end ws.each_element do |e| if 'Table' == e.name table = e break end end first = true table.each_element do |row| next unless 'Row' == row.name if first first = false next end cnt = 0 t = nil row.each_element do |cell| cnt += 1 case cnt when 2 t = cell.first.first.to_s when 4 high = cell.first.first.to_s.to_f if as_time highs[Time.parse(t)] = high else highs[t] = high end break end end end # puts highs highs end end # Wlx end # Weather ox-2.14.17/test/weather/wlxsax.rb000066400000000000000000000021161445411231300166030ustar00rootroot00000000000000require 'time' require 'libxml' module Weather class WLxSax include LibXML::XML::SaxParser::Callbacks attr_accessor :highs def self.parse(filename, as_time) handler = new(as_time) input = IO.open(IO.sysopen(filename)) parser = LibXML::XML::SaxParser.io(input) parser.callbacks = handler parser.parse input.close # puts handler.highs handler.highs end def initialize(as_time) @as_time = as_time @highs = {} @time = nil @row = 0 @cell = 0 end def on_start_element(name, attributes) case name when 'Cell' @cell += 1 when 'Row' @row += 1 @cell = 0 end end def on_characters(chars) chars.strip! return if chars.empty? return unless 1 < @row case @cell when 2 if @as_time @time = Time.parse(chars) else @time = chars end when 4 @highs[@time] = chars.to_f end end def on_error(msg) puts msg end end # WLxSax end # Weather ox-2.14.17/test/weather/wno.rb000066400000000000000000000017231445411231300160630ustar00rootroot00000000000000require 'time' require 'nokogiri' module Weather class WNo def self.parse(filename, as_time) highs = {} doc = Nokogiri::XML::Document.parse(File.open(filename)) # table = doc.xpath('/Workbook/Worksheet/Table') # fails to return any nodes ws = nil table = nil doc.root.elements.each do |e| if 'Worksheet' == e.name ws = e break end end ws.elements.each do |e| if 'Table' == e.name table = e break end end first = true table.elements.each do |row| next unless 'Row' == row.name if first first = false next end t = row.elements[1].child.child.to_s high = row.elements[3].child.child.to_s.to_f if as_time highs[Time.parse(t)] = high else highs[t] = high end end # puts highs highs end end # WNo end # Weather ox-2.14.17/test/weather/wnosax.rb000066400000000000000000000022201445411231300165700ustar00rootroot00000000000000require 'time' require 'nokogiri' module Weather class WNoSax < ::Nokogiri::XML::SAX::Document attr_accessor :highs def self.parse(filename, as_time) handler = new(as_time) nohand = Nokogiri::XML::SAX::Parser.new(handler) input = IO.open(IO.sysopen(filename)) nohand.parse(input) input.close # puts handler.highs handler.highs end def initialize(as_time) super @as_time = as_time @highs = {} @time = nil @row = 0 @cell = 0 end def start_element(name, attrs = []) case name when 'Cell' @cell += 1 when 'Row' @row += 1 @cell = 0 end end def characters(text) text.strip! return if text.empty? return unless 1 < @row case @cell when 2 if @as_time # @time = Time.parse(text) @time = Time.at(text.to_f) else @time = text end when 4 @highs[@time] = text.to_f end end def error(message) puts message end def warning(message) puts message end end # WNoSax end # Weather ox-2.14.17/test/weather/wox.rb000066400000000000000000000010321445411231300160660ustar00rootroot00000000000000require 'time' require 'ox' module Weather class WOx def self.parse(filename, as_time) highs = {} doc = Ox.load_file(filename) table = doc.locate('Workbook/Worksheet/Table')[0] table.nodes[19..-1].each do |row| # skips Column elements and first Row t = row.nodes[1].nodes[0].nodes[0] high = row.nodes[3].nodes[0].nodes[0].to_f if as_time highs[Time.parse(t)] = high else highs[t] = high end end highs end end # WOx end # Weather ox-2.14.17/test/weather/wsax.rb000066400000000000000000000016311445411231300162400ustar00rootroot00000000000000require 'ox' module Weather class WSax < ::Ox::Sax attr_accessor :highs def self.parse(filename, as_time) handler = new(as_time) input = IO.open(IO.sysopen(filename)) Ox.sax_parse(handler, input) input.close # puts handler.highs handler.highs end def initialize(as_time) super @as_time = as_time @highs = {} @time = nil @row = 0 @cell = 0 end def start_element(name) case name when :Cell @cell += 1 when :Row @row += 1 @cell = 0 end end def value(v) return unless 1 < @row case @cell when 2 if @as_time @time = v.as_time else @time = v.as_s end when 4 @highs[@time] = v.as_f end end def error(message, line, column) puts message end end # WSax end # Weather ox-2.14.17/xml/000077500000000000000000000000001445411231300131125ustar00rootroot00000000000000ox-2.14.17/xml/attr.xml000066400000000000000000000000501445411231300146010ustar00rootroot00000000000000 ox-2.14.17/xml/comment.xml000066400000000000000000000000541445411231300152750ustar00rootroot00000000000000 ox-2.14.17/xml/empty.xml000066400000000000000000000000271445411231300147710ustar00rootroot00000000000000 ox-2.14.17/xml/env.xml000066400000000000000000000021111445411231300144170ustar00rootroot00000000000000 eJPT0203AF5 Gavin/virtualbox 2010-07-30T14:54:52.233108006+09:00 2010-08-03T14:05:39.865942000+09:00 ohler ilo ilo d8:d3:85:c0:8e:dc ilo 10.251.14.238 20 eth0 eth0 d8:d3:85:b9:26:54 1 v120 117.55.210.164 29 mJPT0203AF5 tCentOS_5.5_x64_en virtualbox gavin100 117.55.210.161 208.67.222.222 -9 ox-2.14.17/xml/loner.xml000066400000000000000000000000361445411231300147520ustar00rootroot00000000000000 ox-2.14.17/xml/mixed.xml000066400000000000000000000001701445411231300147400ustar00rootroot00000000000000 Second ox-2.14.17/xml/nest.xml000066400000000000000000000002671445411231300146120ustar00rootroot00000000000000 mutant 5 dog ox-2.14.17/xml/sample.xml000066400000000000000000000001041445411231300151100ustar00rootroot00000000000000 a string ox-2.14.17/xml/wFractal.xml000066400000000000000000000706251445411231300154110ustar00rootroot00000000000000 wFractal Fractal 2010-10-08T12:22:12.985217558+09:00 2010-10-08T12:22:12.985217558+09:00 kvh New iFractal_Systems Isolated 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 APSEG v4076 4076 New Isolated 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 Ext v4060 4060 New 110.50.78.24 29 Public 100 sJPTMCV107A1-2 110.50.78.26 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 110.50.78.27 110.50.78.25 Fractal-public v125 125 New 10.128.0.128 25 Shared 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 FW v4059 4059 New 10.128.3.0 25 Shared 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 LB v4058 4058 New FJT-IASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.26 4076 5 mCN701504TM FJTDBNSF01 10.251.2.179 S01 eCN701504TM New FJT-OASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.27 4076 5 mCN701504TN FJTDBNSF01 10.251.12.46 S01 eCN701504TN New FJT-CASCR01 Windows_2008_Standard_x32_jp fatuzi69 -9 APSEG Ext 4076 4060 mCN700908C2 10.251.1.232 S01 eCN700908C2 New ACE-IASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.28 4076 5 mCN701802BK ACEDBNSF01 10.251.7.95 E01 eCN701802BK New ACE-OASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.29 4076 5 mCN701802BM ACEDBNSF01 10.251.5.121 E01 eCN701802BM New ACE-CASCR01 Windows_2008_Standard_x32_jp fatuzi69 -9 APSEG Ext 4076 4060 mCN701802BN 10.251.9.120 E01 eCN701802BN New FJT-IASRM01 Windows_2008_Standard_x32_jp defota29 10.128.3.126 -9 v4058 10.128.3.1 v4076 LB 10.128.3.3 4058 4076 4058 mCN70090BPP 10.251.13.220 S01 eCN70090BPP New FJT-IASRM02 Windows_2008_Standard_x32_jp defota29 10.128.3.126 -9 v4058 10.128.3.2 v4076 LB 10.128.3.4 4058 4076 4058 mCN701102PM 10.251.14.172 S01 eCN701102PM New FJT-OASRM01 Windows_2008_Standard_x32_jp ratoka99 10.128.3.122 -9 v4058 10.128.3.1 v4076 LB 10.128.3.5 4058 4076 4058 mCN701500E9 10.251.13.207 S01 eCN701500E9 New FJT-OASRM02 Windows_2008_Standard_x32_jp ratoka99 10.128.3.122 -9 v4058 10.128.3.2 v4076 LB 10.128.3.6 4058 4076 4058 mCN701500EB 10.251.14.143 S01 eCN701500EB New FJT-CASVP01 Windows_2008_Standard_x32_jp ratoka99 10.128.0.129 -9 v4059 10.128.0.139 v4076 4059 4076 mCN701500EC 10.251.13.184 S01 eCN701500EC New ACE-IASRM01 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.1 v4076 LB 10.128.3.9 4058 4076 4058 mCN701902B8 10.251.9.114 E01 eCN701902B8 New ACE-IASRM02 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.2 v4076 LB 10.128.3.10 4058 4076 4058 mCN701802BX 10.251.7.18 E01 eCN701802BX New ACE-OASRM01 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.7 v4076 LB 10.128.3.11 4058 4076 4058 mCN701802C9 10.251.11.45 E01 eCN701802C9 New ACE-OASRM02 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.8 v4076 LB 10.128.3.12 4058 4076 4058 mCN701802CC 10.251.6.174 E01 eCN701802CC New ACE-CASVP01 Windows_2008_Standard_x32_jp zoteru30 10.128.0.129 -9 v4059 10.128.0.147 v4076 4059 4076 mCN701902BC 10.251.11.119 E01 eCN701902BC New FJTDBNSF01 100 10.128.16.26 10.128.16.27 d800000020694.cvol28 10.128.16.2 ACEDBNSF01 100 10.128.16.28 10.128.16.29 d800000020694.cvol29 10.128.16.2 Fractal_FW v4059 v125 27 4059 125 addr 10.128.0.254 netbits 25 addr 110.50.78.28 netbits 29 pod_web factal_custom addr 110.50.79.96 netbits 27 Fractal_VIP1_LB 110.50.79.98 10.128.0.132 110.50.79.99 10.128.0.134 110.50.79.100 10.128.0.138 110.50.79.101 10.128.0.136 110.50.79.102 10.128.0.142 110.50.79.103 10.128.0.146 110.50.79.104 10.128.0.139 110.50.79.105 10.128.0.147 10.128.0.129 addr 10.128.3.0 netbits 25 h4059 New 110.50.79.97 Fractal_VIP1_LB 10.128.0.132 7100 10.128.3.3 7100 10.128.3.4 7100 7101 10.128.3.3 7101 10.128.3.4 7101 7100 FJT-IASRM01 7100 FJT-IASRM02 7100 7101 FJT-IASRM01 7101 FJT-IASRM02 7101 4058 4059 v4058 v4059 10.128.3.126 10.128.0.129 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.132 New Fractal_VIP2_LB 10.128.0.134 7100 10.128.3.5 7100 10.128.3.6 7100 7101 10.128.3.5 7101 10.128.3.6 7101 7100 FJT-OASRM01 7100 FJT-OASRM02 7100 7101 FJT-OASRM01 7101 FJT-OASRM02 7101 4058 4059 v4058 v4059 10.128.3.125 10.128.0.130 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.134 New Fractal_VIP3_LB 10.128.0.138 443 10.128.3.5 443 10.128.3.6 443 443 FJT-OASRM01 443 FJT-OASRM02 443 4058 4059 v4058 v4059 10.128.3.122 10.128.0.135 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.138 New Fractal_VIP4_LB 10.128.0.136 7100 10.128.3.9 7100 10.128.3.10 7100 7101 10.128.3.9 7101 10.128.3.10 7101 7100 ACE-IASRM01 7100 ACE-IASRM02 7100 7101 ACE-IASRM01 7101 ACE-IASRM02 7101 4058 4059 v4058 v4059 10.128.3.126 10.128.0.129 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.136 New Fractal_VIP5_LB 10.128.0.142 7100 10.128.3.11 7100 10.128.3.12 7100 7101 10.128.3.11 7101 10.128.3.12 7101 7100 ACE-OASRM01 7100 ACE-OASRM02 7100 7101 ACE-OASRM01 7101 ACE-OASRM02 7101 4058 4059 v4058 v4059 10.128.3.121 10.128.0.137 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.142 New Fractal_VIP6_LB 10.128.0.146 80 10.128.3.11 80 10.128.3.12 80 80 ACE-OASRM01 80 ACE-OASRM02 80 4058 4059 v4058 v4059 10.128.3.118 10.128.0.143 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.146 New admin fatuzi69 New aadmin.Fractal_Systems w27757 Modify 2010-10-07T10:46:24.204777000+09:00 New w27757 Modify 2010-10-07T11:24:06.277349000+09:00 Completed w27779 Modify 2010-10-07T13:50:55.031271000+09:00 New w27779 Modify 2010-10-07T14:12:36.521032000+09:00 Completed w27805 Modify 2010-10-07T17:07:00.591538000+09:00 New w27805 Modify 2010-10-07T17:28:55.812314000+09:00 Completed w27831 Modify 2010-10-08T09:53:38.694846000+09:00 New w27831 Modify 2010-10-08T10:21:36.246424000+09:00 Completed ox-2.14.17/xml/wFractal_report.xml000066400000000000000000001263071445411231300170030ustar00rootroot00000000000000 wFractal Fractal 2010-10-08T12:22:12.985217558+09:00 2010-10-08T12:22:12.985217558+09:00 kvh New iFractal_Systems Isolated 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 APSEG v4076 4076 New Isolated 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 Ext v4060 4060 New 110.50.78.24 29 Public 100 sJPTMCV107A1-2 110.50.78.26 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 110.50.78.27 110.50.78.25 Fractal-public v125 125 New 10.128.0.128 25 Shared 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 FW v4059 4059 New 10.128.3.0 25 Shared 10 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 LB v4058 4058 New FJT-IASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.26 4076 5 mCN701504TM FJTDBNSF01 10.251.2.179 S01 eCN701504TM New FJT-OASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.27 4076 5 mCN701504TN FJTDBNSF01 10.251.12.46 S01 eCN701504TN New FJT-CASCR01 Windows_2008_Standard_x32_jp fatuzi69 -9 APSEG Ext 4076 4060 mCN700908C2 10.251.1.232 S01 eCN700908C2 New ACE-IASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.28 4076 5 mCN701802BK ACEDBNSF01 10.251.7.95 E01 eCN701802BK New ACE-OASDB01 Windows_2008_Standard_x32_jp fatuzi69 10.128.16.1 -9 APSEG storage 10.128.16.29 4076 5 mCN701802BM ACEDBNSF01 10.251.5.121 E01 eCN701802BM New ACE-CASCR01 Windows_2008_Standard_x32_jp fatuzi69 -9 APSEG Ext 4076 4060 mCN701802BN 10.251.9.120 E01 eCN701802BN New FJT-IASRM01 Windows_2008_Standard_x32_jp defota29 10.128.3.126 -9 v4058 10.128.3.1 v4076 LB 10.128.3.3 4058 4076 4058 mCN70090BPP 10.251.13.220 S01 eCN70090BPP New FJT-IASRM02 Windows_2008_Standard_x32_jp defota29 10.128.3.126 -9 v4058 10.128.3.2 v4076 LB 10.128.3.4 4058 4076 4058 mCN701102PM 10.251.14.172 S01 eCN701102PM New FJT-OASRM01 Windows_2008_Standard_x32_jp ratoka99 10.128.3.122 -9 v4058 10.128.3.1 v4076 LB 10.128.3.5 4058 4076 4058 mCN701500E9 10.251.13.207 S01 eCN701500E9 New FJT-OASRM02 Windows_2008_Standard_x32_jp ratoka99 10.128.3.122 -9 v4058 10.128.3.2 v4076 LB 10.128.3.6 4058 4076 4058 mCN701500EB 10.251.14.143 S01 eCN701500EB New FJT-CASVP01 Windows_2008_Standard_x32_jp ratoka99 10.128.0.129 -9 v4059 10.128.0.139 v4076 4059 4076 mCN701500EC 10.251.13.184 S01 eCN701500EC New ACE-IASRM01 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.1 v4076 LB 10.128.3.9 4058 4076 4058 mCN701902B8 10.251.9.114 E01 eCN701902B8 New ACE-IASRM02 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.2 v4076 LB 10.128.3.10 4058 4076 4058 mCN701802BX 10.251.7.18 E01 eCN701802BX New ACE-OASRM01 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.7 v4076 LB 10.128.3.11 4058 4076 4058 mCN701802C9 10.251.11.45 E01 eCN701802C9 New ACE-OASRM02 Windows_2008_Standard_x32_jp zoteru30 10.128.3.118 -9 v4058 10.128.3.8 v4076 LB 10.128.3.12 4058 4076 4058 mCN701802CC 10.251.6.174 E01 eCN701802CC New ACE-CASVP01 Windows_2008_Standard_x32_jp zoteru30 10.128.0.129 -9 v4059 10.128.0.147 v4076 4059 4076 mCN701902BC 10.251.11.119 E01 eCN701902BC New FJTDBNSF01 100 10.128.16.26 10.128.16.27 d800000020694.cvol28 10.128.16.2 ACEDBNSF01 100 10.128.16.28 10.128.16.29 d800000020694.cvol29 10.128.16.2 Fractal_FW v4059 v125 27 4059 125 addr 10.128.0.254 netbits 25 addr 110.50.78.28 netbits 29 pod_web factal_custom addr 110.50.79.96 netbits 27 Fractal_VIP1_LB 110.50.79.98 10.128.0.132 110.50.79.99 10.128.0.134 110.50.79.100 10.128.0.138 110.50.79.101 10.128.0.136 110.50.79.102 10.128.0.142 110.50.79.103 10.128.0.146 110.50.79.104 10.128.0.139 110.50.79.105 10.128.0.147 10.128.0.129 addr 10.128.3.0 netbits 25 h4059 New 110.50.79.97 Fractal_VIP1_LB 10.128.0.132 7100 10.128.3.3 7100 10.128.3.4 7100 7101 10.128.3.3 7101 10.128.3.4 7101 7100 FJT-IASRM01 7100 FJT-IASRM02 7100 7101 FJT-IASRM01 7101 FJT-IASRM02 7101 4058 4059 v4058 v4059 10.128.3.126 10.128.0.129 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.132 New Fractal_VIP2_LB 10.128.0.134 7100 10.128.3.5 7100 10.128.3.6 7100 7101 10.128.3.5 7101 10.128.3.6 7101 7100 FJT-OASRM01 7100 FJT-OASRM02 7100 7101 FJT-OASRM01 7101 FJT-OASRM02 7101 4058 4059 v4058 v4059 10.128.3.125 10.128.0.130 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.134 New Fractal_VIP3_LB 10.128.0.138 443 10.128.3.5 443 10.128.3.6 443 443 FJT-OASRM01 443 FJT-OASRM02 443 4058 4059 v4058 v4059 10.128.3.122 10.128.0.135 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.138 New Fractal_VIP4_LB 10.128.0.136 7100 10.128.3.9 7100 10.128.3.10 7100 7101 10.128.3.9 7101 10.128.3.10 7101 7100 ACE-IASRM01 7100 ACE-IASRM02 7100 7101 ACE-IASRM01 7101 ACE-IASRM02 7101 4058 4059 v4058 v4059 10.128.3.126 10.128.0.129 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.136 New Fractal_VIP5_LB 10.128.0.142 7100 10.128.3.11 7100 10.128.3.12 7100 7101 10.128.3.11 7101 10.128.3.12 7101 7100 ACE-OASRM01 7100 ACE-OASRM02 7100 7101 ACE-OASRM01 7101 ACE-OASRM02 7101 4058 4059 v4058 v4059 10.128.3.121 10.128.0.137 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.142 New Fractal_VIP6_LB 10.128.0.146 80 10.128.3.11 80 10.128.3.12 80 80 ACE-OASRM01 80 ACE-OASRM02 80 4058 4059 v4058 v4059 10.128.3.118 10.128.0.143 255.255.255.128 255.255.255.128 10.128.0.254 RESOURCE_TYPE_FAST_L4 fastL4 LB_METHOD_ROUND_ROBIN source_addr b10.128.0.146 New admin fatuzi69 New aadmin.Fractal_Systems w27757 Modify 2010-10-07T10:46:24.204777000+09:00 New w27757 Modify 2010-10-07T11:24:06.277349000+09:00 Completed w27779 Modify 2010-10-07T13:50:55.031271000+09:00 New w27779 Modify 2010-10-07T14:12:36.521032000+09:00 Completed w27805 Modify 2010-10-07T17:07:00.591538000+09:00 New w27805 Modify 2010-10-07T17:28:55.812314000+09:00 Completed w27831 Modify 2010-10-08T09:53:38.694846000+09:00 New w27831 Modify 2010-10-08T10:21:36.246424000+09:00 Completed ox-2.14.17/xml/wr.xml000066400000000000000000000367161445411231300143010ustar00rootroot00000000000000 w23461 23461 2010-08-09T18:25:11.389608495+09:00 2010-08-10T15:52:54.806533000+09:00 ohler Completed iTDC_SOFTWARE 117.55.210.168 29 Public 10 sJPTMCV107A1-2 117.55.210.170 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 117.55.210.171 117.55.210.169 TDC_Public v121 121 New 10.128.2.176 29 Shared 0 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 mira v4070 4070 New 10.128.2.184 29 Shared 0 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 kaname v4069 4069 New 10.128.2.192 29 Shared 0 sJPTMCV107A1-2 sJPTMCV105B1 sJPTMCV106B1 sJPTMCV108A1-2 teresa v4066 4066 New yoshika CentOS_5.5_x64_jp zigeyi22 10.128.2.190 -9 teresa 10.128.2.193 kaname 10.128.2.185 4066 4069 mCN701802GY 10.251.15.155 E01 eCN701802GY New mio CentOS_5.5_x64_jp zigeyi22 10.128.2.190 -9 teresa 10.128.2.194 kaname 10.128.2.186 4066 4069 mCN701802H9 10.251.1.195 E01 eCN701802H9 New charlotte CentOS_5.5_x64_jp zigeyi22 10.128.2.193 -9 teresa 10.128.2.195 4066 mCN701802FJ 10.251.11.205 S01 eCN701802FJ New erica CentOS_5.5_x64_jp zigeyi22 10.128.2.193 -9 teresa 10.128.2.196 4066 mCN701802FK 10.251.2.19 S01 eCN701802FK New lucchini CentOS_5.5_x64_jp zigeyi22 10.128.2.193 -9 teresa 10.128.2.197 4066 mJPT0203AF6 10.251.5.149 P01 eJPT0203AF6 New sanya CentOS_5.5_x64_jp zigeyi22 10.128.2.193 -9 teresa 10.128.2.198 4066 mJPT0203AF7 10.251.11.230 P01 eJPT0203AF7 New TDC_Sftw_Eng_FW mira TDC_Public 29 4070 121 addr 10.128.2.182 netbits 29 addr 117.55.210.172 netbits 29 pod_web pod_mail_client pod_mail_server pod_dns_ntp pod_ssh pod_management pod_rdp pod_ftp addr 110.50.79.136 netbits 29 TDC_Sftw_Eng_LB 110.50.79.138 10.128.2.180 10.128.2.177 addr 10.128.2.184 netbits 29 h4070 New 110.50.79.137 TDC_Sftw_Eng_LB 10.128.2.180 80 4069 4070 kaname mira 10.128.2.190 10.128.2.177 255.255.255.248 255.255.255.248 10.128.2.182 RESOURCE_TYPE_FAST_L4 10.128.2.186 80 10.128.2.185 80 mio 80 yoshika 80 fastL4 LB_METHOD_ROUND_ROBIN b10.128.2.180.80 New admin zigeyi22 New aadmin.TDC_SOFTWARE w23461 Modify 2010-08-09T17:50:26.648823000+09:00 New w23461 Modify 2010-08-09T17:50:28.649910000+09:00 Partial w23461 Modify 2010-08-09T18:22:04.092542000+09:00 Completed 1500 ox-2.14.17/xml/zoo.xml000066400000000000000000000006441445411231300144470ustar00rootroot00000000000000 2 3 5.7 Hello There 1288724706.500122 ox-2.14.17/xml/zoo2.xml000066400000000000000000000021621445411231300145260ustar00rootroot00000000000000 2 3 5.7 boa Godzilla PGJhc2U2ND4= 1288724706.500122 0 1 5555 75932 55 5.6 1288724706.500122 silly symbol 1 cat two 1288724706.500123 37 77 cnt 123 37 77 88 ate in prime 3