"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.utf8Decode = void 0;

var C = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Collections/Immutable/Chunk"));

var Tuple = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Collections/Immutable/Tuple"));

var T = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Effect"));

var M = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Effect/Managed"));

var Ref = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Effect/Ref"));

var Transduce = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Effect/Stream/Transducer"));

var _Equal = /*#__PURE__*/require("@effect-ts/core/Equal");

var _Function = /*#__PURE__*/require("@effect-ts/core/Function");

var O = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("@effect-ts/core/Option"));

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function isTwoByteSequenceStart(b) {
  return (b & 0xe0) === 0xc0;
}

function isThreeByteSequenceStart(b) {
  return (b & 0xf0) === 0xe0;
}

function isFourByteSequenceStart(b) {
  return (b & 0xf8) === 0xf0;
}

function computeSplit(chunk) {
  const length = chunk.length;

  if (length >= 1 && (isTwoByteSequenceStart(C.unsafeGet_(chunk, length - 1)) || isThreeByteSequenceStart(C.unsafeGet_(chunk, length - 1)) || isFourByteSequenceStart(C.unsafeGet_(chunk, length - 1)))) {
    return length - 1;
  } else if (length >= 2 && (isThreeByteSequenceStart(C.unsafeGet_(chunk, length - 2)) || isFourByteSequenceStart(C.unsafeGet_(chunk, length - 2)))) {
    return length - 2;
  } else if (length >= 3 && isFourByteSequenceStart(C.unsafeGet_(chunk, length - 3))) {
    return length - 3;
  } else {
    return length;
  }
}

const utf8DecodeInternal = /*#__PURE__*/new Transduce.Transducer( /*#__PURE__*/M.map_( /*#__PURE__*/Ref.makeManagedRef( /*#__PURE__*/C.empty()), stateRef => O.fold(() => T.chain_(Ref.getAndSet_(stateRef, C.empty()), leftovers => {
  if (C.isEmpty(leftovers)) {
    return T.succeed(C.empty());
  } else {
    return T.succeed(C.single(String.fromCharCode(...C.toArray(leftovers))));
  }
}), bytes => Ref.modify_(stateRef, leftovers => {
  const concat = C.concat_(leftovers, bytes);
  const tuple = C.splitAt_(concat, computeSplit(concat));
  const toConvert = Tuple.get_(tuple, 0);
  const newLeftovers = Tuple.get_(tuple, 1);

  if (C.isEmpty(toConvert)) {
    return Tuple.tuple(C.empty(), C.materialize(newLeftovers));
  } else {
    return Tuple.tuple(C.single(String.fromCharCode(...C.toArray(toConvert))), C.materialize(newLeftovers));
  }
}))));
/**
 * Decodes chunks of UTF-8 `Byte`s into strings.
 */

const utf8Decode =
/*#__PURE__*/
// Handle optional byte order mark
Transduce.branchAfter(3, bytes => C.corresponds_(bytes, C.from([-17, -69, -65]), _Equal.number.equals) ? utf8DecodeInternal : Transduce.andThen(utf8DecodeInternal)(Transduce.prepend(bytes)));
exports.utf8Decode = utf8Decode;
//# sourceMappingURL=utf8Decode.js.map