field.ts 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /**
  2. * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import * as Column from '../../common/column'
  7. import * as TokenColumn from '../../common/text/column/token'
  8. import { Tokens } from '../../common/text/tokenizer'
  9. import * as Data from '../data-model'
  10. import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../../common/text/number-parser'
  11. export default function CifTextField(tokens: Tokens, rowCount: number): Data.Field {
  12. const { data, indices } = tokens;
  13. const str: Data.Field['str'] = row => {
  14. const ret = data.substring(indices[2 * row], indices[2 * row + 1]);
  15. if (ret === '.' || ret === '?') return '';
  16. return ret;
  17. };
  18. const int: Data.Field['int'] = row => {
  19. return fastParseInt(data, indices[2 * row], indices[2 * row + 1]) || 0;
  20. };
  21. const float: Data.Field['float'] = row => {
  22. return fastParseFloat(data, indices[2 * row], indices[2 * row + 1]) || 0;
  23. };
  24. const presence: Data.Field['presence'] = row => {
  25. const s = indices[2 * row];
  26. if (indices[2 * row + 1] - s !== 1) return Data.ValuePresence.Present;
  27. const v = data.charCodeAt(s);
  28. if (v === 46 /* . */) return Data.ValuePresence.NotSpecified;
  29. if (v === 63 /* ? */) return Data.ValuePresence.Unknown;
  30. return Data.ValuePresence.Present;
  31. };
  32. return {
  33. isDefined: true,
  34. rowCount,
  35. str,
  36. int,
  37. float,
  38. presence,
  39. areValuesEqual: TokenColumn.areValuesEqualProvider(tokens),
  40. stringEquals(row, v) {
  41. const s = indices[2 * row];
  42. const value = v || '';
  43. if (!value && presence(row) !== Data.ValuePresence.Present) return true;
  44. const len = value.length;
  45. if (len !== indices[2 * row + 1] - s) return false;
  46. for (let i = 0; i < len; i++) {
  47. if (data.charCodeAt(i + s) !== value.charCodeAt(i)) return false;
  48. }
  49. return true;
  50. },
  51. toStringArray(params) { return Column.createAndFillArray(rowCount, str, params); },
  52. toIntArray(params) { return Column.createAndFillArray(rowCount, int, params); },
  53. toFloatArray(params) { return Column.createAndFillArray(rowCount, float, params); }
  54. }
  55. }