/*
* MathGraph32 Javascript : Software for animating online dynamic mathematics figures
* https://www.mathgraph32.org/
* @Author Yves Biton (yves.biton@sesamath.net)
* @License: GNU AGPLv3 https://www.gnu.org/licenses/agpl-3.0.html
*/
import utf8 from '../../outilsExternes/utf8Utils'
import BinaryParser from '../../outilsExternes/binaryParser/binary-parser'
export default DataOutputStream
/**
* Classe servant à enregistrer une figure depuis un flux binaire base 64
* contenu dans un tableau de bytes.
* @constructor
* @returns {void}
*/
function DataOutputStream () {
this.bp = new BinaryParser(true, true) // Poids forts en premeir et exceptions gérées
this.listeNomsClasse = [] // Liste contenant les noms des classes des objets de la liste enregistrée
this.ba = []
}
DataOutputStream.nat_png = 0
DataOutputStream.nat_gif = 1
DataOutputStream.nat_jpg = 2
DataOutputStream.nat_noImage = 255 // Non signé en java
/**
* Enregistrement d'un entier sur 4 octets dans le flux
* @param {number} ent
* @returns {void}
*/
DataOutputStream.prototype.writeInt = function (ent) {
// Corrigé version mtgApp. Ne marche pas
let i
if (ent === -1) {
for (i = 0; i < 4; i++) this.ba.push(255)
} else {
const r = this.bp.fromInt(ent)
for (i = 0; i < r.length; i++) this.ba.push(r.charCodeAt(i))
}
}
/**
* Enregistrement d'un entier sur 2 octets dans le flux
* @param {number} ent
* @returns {void}
*/
DataOutputStream.prototype.writeShortInt = function (ent) {
// Corrigé version mtgApp. Ne marche pas
let i
if (ent === -1) for (i = 0; i < 2; i++) this.ba.push(255)
else {
const r = this.bp.fromShort(ent)
for (i = 0; i < r.length; i++) this.ba.push(r.charCodeAt(i))
}
}
/**
* Enregistrement d'un byte dans le flux
* @param {number} b
* @returns {void}
*/
DataOutputStream.prototype.writeByte = function (b) {
this.ba.push(b)
}
/**
* Enregistrement d'un booléen dans le flux
* @param {boolean} b
* @returns {void}
*/
DataOutputStream.prototype.writeBoolean = function (b) {
this.ba.push(b ? 1 : 0)
}
/**
* Enregistrement d'un double dans le flux
* @param {number} d
* @returns {void}
*/
DataOutputStream.prototype.writeDouble = function (d) {
const r = this.bp.fromDouble(d)
for (let i = 0; i < r.length; i++) this.ba.push(r.charCodeAt(i))
}
/**
* Enregistrement d'un float dans le flux.
* @param {number} d
* @returns {void}
*/
DataOutputStream.prototype.writeFloat = function (d) {
const r = this.bp.fromFloat(d)
for (let i = 0; i < r.length; i++) this.ba.push(r.charCodeAt(i))
}
/**
* Enregistrement d'un tableau d'entiers décrivant une image dans le flux
* @param {number[]} im
* @returns {void}
*/
DataOutputStream.prototype.writeBufferedImage = function (im) {
this.writeInt(im.length)
this.ba = this.ba.concat(im)
}
/**
* Enregistrement d'une chaîne de caractères dans le flux
* La longueur de la chaîne est d'abod enregistrée
* @param {string} ch
* @returns {void}
*/
DataOutputStream.prototype.writeUTF = function (ch) {
const st = utf8.encode(ch)
this.writeShortInt(st.length)
for (let i = 0; i < st.length; i++) this.ba.push(st[i])
}
/**
* Enregistrement d'une chaîne de caractères dans le flux
* La longueur de la chaîne n'est pas enregistrée.
* @param {string} ch
* @returns {void}
*/
DataOutputStream.prototype.writeCString = function (ch) {
for (let i = 0; i < ch.length; i++) {
this.writeByte(ch.charCodeAt(i))
}
}
/**
* Enregistrement d'un objet dans le flux
* Si une m^ême classe a déjà été enregistrée, on enregistre l'indice du nom
* de la classe de cet objet dans le flux et sinon on enregistre -1 suivi du
* numéro de version de l'objet et du nom de la classe.
* L'objet s'enregistre ensuite dans le flux.
* @param {COb} ob
* @returns {void}
*/
DataOutputStream.prototype.writeObject = function (ob) {
let i
const nomClasse = ob.className
const numVer = ob.numeroVersion() // Numéro de version
// On regarde d'abord si un objet de cette classe a déjà été enregistré dans le flux.
// Si oui on enregistre dans le flux son indice dans la liste des classes déjà
// chargées dans la liste listeNomsClasses.
// Sinon on enregistre un short FFFF suivi du numéro de version de l'objet
// suivi du nom de la classe
let trouve = false
for (i = 0; (i < this.listeNomsClasse.length) && !trouve; i++) {
const ch = this.listeNomsClasse[i]
if (ch === nomClasse) {
trouve = true
break
}
}
if (trouve) {
this.writeInt(i)
} else {
this.writeInt(-1)
this.writeInt(numVer)
this.writeUTF(nomClasse)
this.listeNomsClasse.push(nomClasse)
}
ob.write(this, ob.listeProprietaire)
}
/**
* Fonction renvoyant le code de nature d'iamge correspondant à l'extension ext
* @param ext
* @returns {number}
*/
DataOutputStream.getNatImage = function (ext) {
switch (ext) {
case 'jpg':
case 'jpeg':
return DataOutputStream.nat_jpg
case 'gif':
return DataOutputStream.nat_gif
default :
return DataOutputStream.nat_png
}
}